コンストラクタは、オブジェクトを作成します
function Person() {
}
let person1 = new Person()
let person2 = new Person()
person1.name = 'james'
person2.name = 'kobe'
console.log(person1);
console.log(person2);
さんが新しいを通じて人のインスタンスを作成してみましょう、私たちは、異なるインスタンスは、独自の属性を持って見ることができます。
プロト
私たちは、属性の__proto__を持っています、このプロパティは、オブジェクトのプロトタイプを指します、各オブジェクトの下で見ることができます
function Person() {
}
Person.prototype.name = 'chris'
let person = new Person()
let person1 = new Person()
let person2 = new Person()
person1.name = 'james'
person2.name = 'kobe'
console.log(person);
console.log(person1);
console.log(person2);
私たちは、それが何であるかと、その後__proto__プロトタイプの関係、次の__proto__のname属性のプロトタイプが表示されますか?
プロトタイプ
各機能は持っているプロトタイプは、私たちがよく使用prototypeプロパティを持っています
Person.prototype.name = 'chris‘
そこで問題は、エンドポイントでのこの関数のprototypeプロパティは何ですか?この関数のプロトタイプは何ですか?
実際には、プロトタイプは、それはコンストラクタ作成したインスタンスを呼び出している関数オブジェクトのプロトタイプ属性ポイント、この例のPERSON1とのPERSON2でプロトタイプがあります。
それはプロトタイプということは何ですか?理解することができる:(ヌルを除く)すべてのJavaScriptのオブジェクトはそれが作成され、別のオブジェクトに関連付けされ、このオブジェクトは、我々はプロトタイプを呼んで、各オブジェクトは、呼び出されたプロトタイプからプロパティを継承します。
__proto__インスタンスのプロトタイプやコンストラクタを比較することにより、我々は見つけるその人とPerson.prototypeとの関係
person.__proto__ === Person.prototype //true
そのコンストラクタまたはインスタンスへプロトタイププロパティポイントが存在する場合にインスタンスオブジェクトとコンストラクタので、プロトタイプを指すことができますか?
constructor
見つけるのは難しいことではありませんが、各コンストラクタは、このプロパティは、我々は関連するコンストラクタにconstructorプロパティの点を通るコンソールを見つけるコンストラクタを持っています
私たちは、コンストラクタ、インスタンスのプロトタイプ、および例との間の関係を理解するように、我々は例やプロトタイプの関係について話します:
プロトタイプの例の下で
私たちは、プロパティはインスタンスを読み取ることができない場合は、オブジェクトの属性に関連したプロトタイプを見つけることを知って、まだ見つける場合は、プロトタイプをプロトタイプに行きました、これまでにトップレベルを発見されました。
function Person() {
}
console.log(Person.prototype.name); //underfind
Person.prototype.name = 'chris';
var person = new Person();
person.name = 'james';
console.log(person.name) // james 拿到实例的name属性
delete person.name;
console.log(person.name) // chris 拿到原型的name属性
しかし、どのような場合は、それを読んでいませんか?それはどのような次のプロトタイプのプロトタイプですか?
プロトタイプのプロトタイプの下で
通过上面的知识我们知道person.__proto__与Person.protype相等,那么Person.prototype.__proto__下又是什么呢?很显然就是对象实例的__proto__
function Person() { }
let person = new Person()
let obj = new Object()
console.log(Person.prototype.__proto__ === obj.__proto__) //true
console.log(Person.prototype.__proto__ === Object.prototype) //true
console.log(obj.__proto__.__proto__) //null
let obj = new Object();
obj.__proto__.name = 'chris'
obj.name = 'Kevin'
console.log(obj.name) // Kevin
delete obj.name
console.log(obj.name) // chris
原型链
既然我们知道Object的原型,那 Object.prototype的原型呢?
我们可以看到返回一个null,表达的就是已经没有原型了。
最终就是原型和原型链的结构
一些补充
关于 Funtion 中的原型 我们可以会发现 Function.prototype 有些特殊
Function.prototype === Function.__proto__ //true
这样看上去实例的原型和原型的原型是相等的,即是鸡也是蛋。 我们可以参考MDN关于__proto__的解释:
__proto__的读取器(getter)暴露了一个对象的内部 [[Prototype]] 。对于使用对象字面量创建的对象,这个值是
Object.prototype
。对于使用数组字面量创建的对象,这个值是Array.prototype
。对于functions,这个值是Function.prototype
。对于使用 new fun 创建的对象,其中fun是由js提供的内建构造器函数之一(Array
,Boolean
,Date
,Number
,Object
,String
等等),这个值总是fun.prototype。对于用js定义的其他js构造器函数创建的对象,这个值就是该构造器函数的prototype属性。
Object.__proto__ === Function.prototype //true
Object.__proto__ === Function.__proto__ //true
引用冴羽的理解
至于为什么Function.__proto__ === Function.prototype,我认为有两种可能:一是为了保持与其他函数一致,二是就是表明一种关系而已。
简单的说,就是先有的Function,然后实现上把原型指向了Function.prototype,但是我们不能倒过来推测因为Function.__proto__ === Function.prototype,所以Function调用了自己生成了自己。
总结
1、实例对象的__proto__始终指向构造函数的prototype
2、只有构造函数才拥有prototype属性,对象(除了null)都拥有__proto__属性
3、每一个原型对象都有一个constructor属性指向它们的构造函数
4、要读取属性时,先读取实例上的属性,读取不到会在原型链上寻找相应属性
5、原型链按照__proto__的指向下一级对象
6、原型链的尽头始终是null
7、构造函数实例化以后,既是构造函数函数,也是对象
function Foo() {
}
const obj = new Foo()
Foo.prototype === obj.__proto__ //true
obj.constructor === Foo //true
Foo.prototype.__proto__ === Object.prototype //true
Object.prototype.__proto__ === null //true
Object.constructor === Function //true