JavaScript红宝书第8章:对象、类与面向对象编程(2/4)

编程入门 行业动态 更新时间:2024-10-24 20:22:25

JavaScript<a href=https://www.elefans.com/category/jswz/34/1592099.html style=红宝书第8章:对象、类与面向对象编程(2/4)"/>

JavaScript红宝书第8章:对象、类与面向对象编程(2/4)

JavaScript红宝书第8章:对象、类与面向对象编程(2/4)

  • 创建对象
      • 工厂模式解决
        • 工厂模式原理
      • 构造函数模式
        • 构造函数模式和工厂模式区别
        • 创建Person的new实例中间会发生什么
        • 构造函数VS普通函数
        • 构造函数问题与解决方案
      • 原型模式
        • 理解原型
        • 原型层级
        • 原型和in操作符
        • 属性枚举顺序
      • 对象迭代
    • 小结

创建对象

虽然对象字面量和Object构造函数创建对象已非常便捷,但如果创建相同接口(属性和方法)的多个对象,代码会出现大量冗余,为此出现了一些解决方案。

工厂模式解决

工厂模式原理

设计模式中的工厂模式类似与工厂中的造纸机,不用手工造纸,只需要把纸需要的原料放进去就可以生产出来,那么对于避免重复new多个相同方法、属性的对象来说,工厂模式可以解决,代码如下:

function factory(name,age,sex){let obj=new Object();obj.name=name;obj.age=age;obj.sex=sex;return obj;
}
let person1=factory('Jack',18,'man')
let person2=factory('mary',20,'woman')
console.log(typeof person1);//Object

在上述代码中,我们创造一个函数作为工厂,这个函数的作用主要就是让我们传递三个属性值,并且返回一个对象,这时候已经避免了多次new对象创造同样的接口(属性、方法)。但又有新的问题,为什么这里的对象实例类型没有具体的对象标识问题(即新创建的对象是什么类型)。比如Person对象下有person对象实例1和person对象实例2。那么没有就无法通过instanceof 判断是否为某个特定的类型,那么如何解决,这里又要引入一个新的模式,构造函数模式

构造函数模式

构造函数是用于创建特定类型对象的。

function Person(name,age,sex)
{this.name=name;this.age=age;this.sex=sex;this.WhatName=function(){console.log(this.name);}
}
let person=new Person('Jack',18,'man');
let person1=new Person('Mary',20,'woman')
console.log(person instanceof Person);//true

在上述代码中,就解决了无法标识对象为特定类型问题。

构造函数模式和工厂模式区别

构造函数没有显式创建对象。
构造函数没有return返回值。
构造函数的属性和方法都赋给了this。
构造函数首字母大写。大写是规范,小写也不报错。

创建Person的new实例中间会发生什么

1.内存创建新对象
2.对象实例内部Prototype被赋值为构造函数的prototype属性。
3.构造函数内部this指向新对象实例。
4.执行函数代码。
5.构造函数如果有返回且是非空对象,则返回该对象,否则返回新创建对象。

同时,函数表达式(匿名函数)也可以写成构造函数,let Person=function()

如果不想传递参数,则new Person后的()可加可不加。

构造函数VS普通函数

构造和普通唯一区别就是调用方法,构造必须要用new调用,换句话说,构造函数加new就是构造函数调用,不加new则是普通函数。

// 作为构造函数 
let person = new Person("Nicholas", 29, "Software Engineer"); 
person.sayName(); // "Nicholas" 
// 作为函数调用
Person("Greg", 27, "Doctor"); // 添加到 window 对象
window.sayName(); // "Greg"
构造函数问题与解决方案

在构造函数方法中,多个对象实例调用构造函数,会创造多个构造Function实例,如何解决?
把构造函数中的方法放在构造函数外定义。如:

function Person(name,age,sex)
{this.name=name;this.age=age;this.sex=sex;this.WhatName=WhatName
}
function WhatName(){console.log(this.name);
}
let person=new Person('Jack',18,'man');
person.WhatName()

一个方法可以这么搞,如果说构造函数中有多个方法,这么搞必然会导致代码没有很好的聚合性,这个新问题可以通过原型模式解决。

原型模式

每个对象会创造一个prototype属性实例,这个实例是一个对象。这个在构造函数上的原型对象在对象实例中是被共享的。在构造函数中直接赋给对象的,现在可以直接赋给它的原型。

			function Person(){}Person.prototype.name='Jack'Person.prototype.sayName=function(){console.log(this.name)}let person=new Personlet person1=new Personconsole.log(person.sayName === person.sayName);//trueconsole.log(person.name);//Jack

这样就解决了刚才的聚合性问题,既没有创建多个函数实例,也没有通过构造函数之外的函数创建来进行低聚合,而是在原型中新增了一个方法作为共享属性方法。

理解原型

只要创建函数,则为这个函数创造一个prototype属性,默认情况下,所有原型获得一个constructor属性,指回关联的构造函数,自定义构造函数中,原型对象除了会获得constructor属性外,其他方法都继承自Object,火狐和谷歌浏览器可以通过__proto__访问原型,总结一句话:对象实例与构造函数原型有直接联系,但与构造函数本身没有。也就是说,原型是被继承和共享的,而构造函数只是一个模板。
可以通过Object.setPrototypeOf()与Object.create来修改原型,前者是直接修改不建议,后者是创建对象时候直接添加原型。建议。

原型层级

两层搜索,比如构造函数原型中新增一个say方法,又新建一个person1对象实例,在搜索person1的say这个属性的时候,会从person1实例中开始搜索,如果又则返回true,没有则从person1的原型中搜索,又返回true,没有返回false。实例可以读取构造原型的值,但不可以修改。但是可以覆盖,比如可以在对象实例中新建一个say方法,它就会把原型中的say方法覆盖掉。
如何判断这个属性和在实例中还是原型中?
hasOwnProperty方法可以实现,存在实例中返回true,存在原型中返回false。
语法格式:对象实例.hasOwnProperty(“属性名”)

原型和in操作符

in操作符可以判断对象实例中有没有某个属性。但无法判断属性是在实例还是原型中。

console.log("name" in person1); // true 

for in中的in是遍历可枚举的属性索引。包括实例属性和原型属性。
如果只想获得实例属性,可以用Objectg.keys()

let keys = Object.keys(Person.prototype); 
console.log(keys); // "name,age,job,sayName"

如果只想获得实例属性,不论可不可枚举,可以用getOwnProeryNames

let keys = Object.getOwnPropertyNames(Person.prototype); 
console.log(keys); // "[constructor,name,age,job,sayName]"
属性枚举顺序

for-in 循环和 Object.keys()的枚举顺序是不确定的,跟浏览器有关。
Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和 Object.assign()
的枚举顺序是确定性的。先以升序枚举数值键,然后以插入顺序枚举字符串和符号键。在对象字面量中
定义的键以它们逗号分隔的顺序插入。

对象迭代

ES6新增Object.values()和 Object.entries()方法,它们接收一个对象,返回它们内容的数组。Object.values()
返回对象值的数组,Object.entries()返回键/值对的数组。

小结

本文主要讲述红宝书第八章第2节。

更多推荐

JavaScript红宝书第8章:对象、类与面向对象编程(2/4)

本文发布于:2023-11-14 14:30:27,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1587831.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:红宝书   面向对象   对象   JavaScript

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!