function Person() {}
Person.prototype.name = '我是人类'
function Xiaoming() {
this.name = "我叫小明"
}
Xiaoming.prototype = new Person()
p = new Xiaoming()
console.log(p); //Xiaoming{}
res = p.__proto__;
console.log('1');
console.log(res); //Person{} 对象
res = p.__proto__.__proto__;
console.log('2');
console.log(res); //{name:"我是人类"}
res = p.__proto__.__proto__.__proto__;
console.log('3');
console.log(res); //{}
res = p.__proto__.__proto__.__proto__.__proto__;
console.log('4');
console.log(res); //null
console.log('====================');
console.log(Xiaoming.prototype); //Person{}
运行结果:
原型链图:
上述例子为原型及原型链的实例。
原型链和原型
Constructor 构造函数
首先创建构造函数Person,为区别于普通函要求首字母大写
function Person() {}
prototype 原型
每一个函数都有一个prototype属性,prototype属性指向一个对象。
这个对象正是调用该构造函数而创建的实例的原型
(Person.prototype.name是调用构造函数 Person 而创建的实例 person1、person2 的 原型)
function Person() {}
Person.prototype.name = '人类';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // 人类
console.log(person2.name) // 人类
每个JavaScript对象(null除外)在创建的时候都会有与之关联的另一个对象,这个对象就是我们所说的原型,每个对象都会从原型“继承”(通过委托访问)属性。
构造函数和原型实例之间的关系
instance 实例
有个构造函数,我们就可以在原型上创建可以“继承”的属性,并通过 new 操作符创建实例
function Person() {}
Person.prototype.name = '我是人类'
xiaoming = new Person()
proto
每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。
实例Xiaoming.proto 指向 Person.prototype。
console.log(xiaoming.__proto__ === Person.prototype);
constructor 构造函数
原型通过constructor函数访问到构造函数。
console.log(Person === Person.prototype.constructor); // true
实例、构造函数、原型
实例与原型
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型
function Person() {}
Person.prototype.name = '我是人';
var xiaoming = new Person();
xiaoming.name = '我是小明';
console.log(xiaoming.name) // 我是小明
delete xiaoming.name;
console.log(xiaoming.name) // 我是人
当删除实例的属性时,它会向实例的原型查找,通过__proto__。
也就是创造这个实例的构造函数的原型,如果还没有会向原型的原型查找,直至null
原型的原型
原型对象通过Object构造函数生成,实例的__proto__指向构造函数的prototype,
原型链
原型通过__proto__访问原型的原型。
当访问p中的一个非自有属性,通过__proto__连接起来一系列原型、原型的原型、原型的原型的原型直到Object构造函数为止。
补充
console.log(p.constructor === Xiaoming.prototype.constructor);
console.log(Xiaoming.prototype.constructor); //ƒ Person() {}
proto
大多数浏览器支持这个非标准的方法访问原型,但它并不存在于Person.prototype中,来自Object.pertotype,与其说是一个属性,不如说是一个 getter/setter,当使用 obj.proto 时,可以理解成返回了 Object.getPrototypeOf(obj)。
三句话解释原型和原型链
第一句话:prototype是函数的原型对象,即prototype是一个对象,它会被对应的__proto__引用。
第二句话:要知道自己的__proto__引用了哪个prototype,只需要看看是哪个构造函数构造了你,那你的__proto__就是那个构造函数的prototype。
第三句话:所有的构造函数的原型链最后都会引用Object构造函数的原型,即可以理解Object构造函数的原型是所有原型链的最底层,即Object.prototype.__proto===null
作者:宣泽彬
链接:https://www.jianshu.com/p/7119f0ab67c0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
构造函数的所有实例都可以访问构造函数原型中的方法和属性。
也就是把共有的东西统一存放到一个共享空间。这样可以避免相同函数重复声明,减少空间占用,节省内存。
举个例子:
function Person() {}
Person.prototype.name = '我是人类'
console.log(Person.prototype);
function Xiaoming() {
this.name = "我叫小明"
}
Xiaoming.prototype = new Person()
let p = new Xiaoming()
console.log(p); //Xiaoming{}
console.log(Xiaoming.prototype.constructor); //ƒ Person() {}
console.log(Person);
console.log(p.constructor === Xiaoming.prototype.constructor);
res = p.__proto__;
console.log('1');
console.log(res); //Person{} 对象
res = p.__proto__.__proto__;
console.log('2');
console.log(res); //{name:"我是人类"}
res = p.__proto__.__proto__.__proto__;
console.log('3');
console.log(res); //{}
res = p.__proto__.__proto__.__proto__.__proto__;
console.log('4');
console.log(res); //null
console.log('====================');
console.log(Xiaoming.prototype.c); //Person{}
console.log(Xiaoming);
console.log(Xiaoming.prototype.constructor);
console.log(Xiaoming === Xiaoming.prototype.constructor);
function Person() {}
Person.prototype.name = '我是人类'
function Xiaoming() {}
Xiaoming.prototype = new Person()
console.log(Xiaoming.prototype.__proto__);
console.log(Xiaoming.prototype);
let p = new Xiaoming()
console.log(p.id);
console.log(p.name);
console.log(p); //Xiaoming{}
res = p.__proto__;
console.log('1');
console.log(res); //Person{} 对象
console.log(Xiaoming.prototype);
console.log(Person);
res = p.__proto__.__proto__;
console.log('2');
console.log(res); //{name:"我是人类"}
console.log(Xiaoming.prototype.__proto__);
console.log(Person.prototype);
res = p.__proto__.__proto__.__proto__;
console.log('3');
console.log(res); //{}
res = p.__proto__.__proto__.__proto__.__proto__;
console.log('4');
console.log(res); //null
原型链图:
参考文章: