原型
每一个JS对象(null除外)都和一个对象相关联,这个对象就是原型,每一个对象都从原型继承属性
js对象内部包含[[prorotype]]指向原型对象,可以通过__proto__访问
可以通过Object.getPrototypeOf(obj) 来获取对象的原型属性
或者通过isPrototypeOf()来判断某个对象是否为另外一个对象的原型
let obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); //true
console.log(Object.prototype.isPrototypeOf(obj)); //true
let arr = new Array();
console.log(Object.getPrototypeOf(arr) === Array.prototype); //true
let p = { a: 1 };
p1 = Object.create(p);
console.log(Object.getPrototypeOf(p1) === p); //true
设置对象的原型属性
proto
直接操作私有属性,不推荐
let a = { x: 1 };
let b = {
__proto__: a,
};
console.log(Object.getPrototypeOf(b) === a); //true
Object.setPrototypeOf(a,b)
两个参数,第一个参数为要设置原型的对象,第二个为设置对象的新原型,如果第二个参数是NULL或者不是对象的话,会报错
let a = { x: 1 };
let b = {};
Object.setPrototypeOf(b, a);
console.log(Object.getPrototypeOf(b) === a); //true
super
es6新增的一个关键字 super ,可以在类中使用,对象中的super关键字指向该对象的原型(由于super不能单独使用,所以无法打印)
let obj1 = {
fn1() {
return "fn1";
},
};
let obj2 = {
fn2() {
return super.fn1();
},
};
Object.setPrototypeOf(obj2, obj1);
console.log(obj2.fn2()) //fn1
原型链
当我们访问一个对象的属性或者方法时,会在对象本身找,如果没有则会到他的原型对象上找,如果
还没有就回到原型对象的原型对象上去找,找到则返回对应的值,如果直到原型对象为NULL,则返回undefined
function Person() {}
Person.prototype.name = "jerry";
Person.prototype.sayName = function () {
console.log(this.name);
};
let person1 = new Person();
let person2 = new Person();
person1.sayName();
console.log(person1.sayName === person2.sayName); //true
console.log(person1.sayName === Person.prototype.sayName); //true
console.log(Person.prototype.isPrototypeOf(person1)); //true
原型链示意图
(自身普通属性prototype指向Person.prototype(只有函数function有,其他为undefined),原型属性[[prototype]] 指向 Function.prorotype)
实践中的原型
1 查询属性会遍历原型链,有一定的性能问题,要注意代码中的原型链长度,并在必要时分解,以避免潜在的性能问题
2 原型上的属性会被所有实例共享,如果属性值是对象类型,则某个实例更改之后会影响其他实例, 原始类型则不会
function Person() {}
Person.prototype = {
name: "tom",
book: [],
};
let p1 = new Person();
let p2 = new Person();
p1.name = "jerry";
p1.book.push("tom and jerry"); //tom
console.log(p2.name, p2.book); //tom and jerry
这篇文章到这里就结束了,如有错误希望大佬指出