对象属性
- 获取对象属性
Object.getOwnPropertyDescriptor(person1, 'name')
Object.getOwnPropertyDescriptors(person1) - 定义对象属性
Object.defineProperty()
Object.defineProperties() - obj.操作符的理解(原型链)
会先去实例上查找——> 实例的__proto__上查找——>实例的__proto__的__proto__——>Object.prototype——> Object.prototype.proto(null)
上查找 - in操作符理解
单独使用:实例+原型 可枚举
遍历使用:实例+原型 可枚举
Object.hasOwnProperty()只存在于实例中才返回true
其它对象遍历的方式都是只存在于实例,且可枚举(比如Object.keys(),Object.entries(),Object.values()) - 对象属性值
configurable:
是否能通过delete操作符删除
enummerable:
是否能通过for in循环遍历到
Get:
Set:
new关键字发生了什么:
1.生成一个对象
2.把该对象进行[[prototype]]的连接
3.绑定该对象到函数调用的this
4.如果该函数没有返回其它对象,会返回该对象
模拟实现new的过程:
//
function Person(name, age) {
this.name = name;
this.age = age;
}
function factory(func) {
var args1 = Array.prototype.slice.call(arguments, 0, 1)[0];
var args2 = Array.prototype.slice.call(arguments, 1);
var obj = new Object();
obj.__proto__ = func.pro;
var result = func.call(obj, ...args2);
return typeof result === 'object' ? result : obj;
}
var result = factory(Person, 'wangyiman', 23);
console.log(result);
创建对象的方式:
- 工厂方式
- 构造函数
缺点:
每次new都会生成新的实例 - 原型
缺点:
引用类型的变量全局只有一份,改了一处所有的地方都被改了。
非引用类型会被直接"."出来的对象属性屏蔽掉(使用delete可以删除) - 组合模式
- 动态原型
把原型模式放到构造函数内部执行 - 寄生构造函数
有点像工厂模式,但是调用时通过new的,可以扩展原生对象。
继承的本质:
继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。
继承的方式:
- 原型链:
引用类型的原型属性会被所有实例共享,非引用类型的不会被实例共享
function SuperType() {
this.colors = ['red'];
}
function SubType() {
}
SubType.prototype = new SuperType();
let subType1 = new SubType();
subType1.colors = 'green';
console.log(subType1.colors);
let superType1 = new SuperType();
console.log(superType1.colors);
不能向超类型的构造函数传递参数
构造函数:
在超类型原型上定义的方法,对子类型是不可见的。
组合继承:原型式继承:
就是让一个对象继承另一个对象,而不是兴师动众地创建一个构造函数
ES5规范了原型式继承,Object.create方法寄生式:
为了解决多次调用父类构造函数寄生组合式:
为了解决多次调用父类构造函数,同时继承后不改变原来construcotr属性。