对JS中的prototype、__proto__,constructor的理解

首先参考此文章:https://blog.csdn.net/cc18868876837/article/details/81211729

根据参考文章,得到知识点1:

知识点1:一个对象的__proto__属性,指向该对象的构造函数的prototype属性。

然后补充知识点:

知识点2:函数也是对象,对象就需要构造函数,而函数对象的构造函数是Function();

知识点3:函数的prototype属性对应的值,是一个普通对象(不是函数对象)。

知识点4:不是函数的对象,它的默认构造函数是Object();

知识点5:设函数为foo(),带括号的foo()表示调用该函数的表达式。不带括号的foo表示该函数对象。想获取函数的prototype属性时,需要使用foo.prototype,而不能使用foo().prototype。因为带括号的foo()是一个调用该函数的表达式,该表达式的结果是函数的返回值,而不是函数对象自身了。

知识点6:Object()函数,它的prototype属性中所指向的普通对象里,没有__proto__属性。

知识点7:只有函数有prototype属性,而prototype对应的值的constructor属性,指向函数自身。

知识点8:获取一个对象的属性时,如果该对象内部没有这个属性,就从该对象的__proto__所指向的对象去找。

知识点9:一个函数的prototype属性,用来存放该函数构建的对象的共享变量。其机制,就是当访问一个对象的变量而该变量在对象内部不存在时,就访问该对象的__proto__,而该函数构建的对象的__proto__指向该函数的prototype。

知识点10:对于一个对象来说,它的原型就是指它的__proto__指向的对象。

因此可知,对以下代码:

function Foo(){};

let f = new Foo();

1. 根据知识点1,可知f作为一个对象,f 的__proto__属性指向 f 的构造函数的prototype属性。而f的构造函数是谁呢?是Foo()。因此有:

console.log(f.__proto__===Foo.prototype);//true

2. 根据知识点2,可知Foo作为一个函数对象,它的构造函数是Function()。Foo作为对象,它也有__proto__属性,且指向Foo的构造函数Function()的prototype属性。因此有:

console.log(Foo.__proto__===Function.prototype);//true

3. 同理,Function()也是对象,也有__proto__属性,且指向Function的构造函数Function() (就是Function()自己)

console.log(Function.__proto__===Function.prototype);//true

4.根据知识点4,可知一个对象的默认构造函数是Object(),因此对于对象字面量let a = {},a的构造函数是默认构造函数Object()。因此有:

let a = {};
console.log(a.__proto__===Ojbect.prototype);//true

5. 根据知识点3,可知Foo作为函数,它的prototype属性对应的值是一个字面量对象。那么再根据知识点4,这个prototype属性对应的字面量对象的默认构造函数是Object()。因此有:

console.log(Foo.prototype.__proto__===Object.prototype);//true

6. 根据知识点2,Object()作为函数,也是一个对象,它的构造函数也是Function()。因此有:

console.log(Object.__proto__===Function.prototype);//true

7.根据知识点6,有:

console.log(Object.prototype.__proto__===null);//true

8. 根据知识点7,仅函数有prototype属性,该属性的constructor指向函数自身。因此有:

console.log(Foo.prototype.constructor===Foo);//true
console.log(Object.prototype.constructor===Object);//true
console.log(Function.prototype.constructor===Function);//true

9. 根据知识点8。要获取f 的constructor属性时,由于f 内部没有constructor属性,就回去f 的__proto__所指向的对象去找。再根据知识点1,f 的__proto__指向其构造函数 Foo的prototype。因此会从Foo的prototype属性里去找constructor。再根据知识点7,Foo的prototype的constructor指向Foo函数自身。因此最后寻找的结果就是Foo。因此有:

console.log(truef.constructor===Foo);//true

10.根据指示点9,只要用Foo作为构造函数构造的对象,都共享Foo的prototype的变量。因此有:

function Foo(){};
Foo.prototype.myVar="This is myVar";
let f1 = new Foo();
let f2 = new Foo();
console.log(f1.myVar);//"This is myVar"
console.log(f2.myVar);//"This is myVar"
console.log(f1.myVar===f2.myVar);//true
f1.__proto__.var2 = "this is var2";
console.log(f2.var2);//"this is var2"

11. 根据指示点10,f 作为一个对象,它的原型就是它的构造函数Foo的prototype属性指向的值,因此有:

f 的原型 === f.__proto__

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 JavaScript ,每个对象都有一个 __proto__ 属性,指向其构造函数的原型对象。而每个函数都有一个 prototype 属性,指向该函数实例化出来的对象的原型对象。 __proto__ 属性是一个指针,指向该对象的构造函数的原型对象。通过 __proto__ 属性可以访问原型对象的属性和方法。这个属性在 ES6 已经被标准化,可以用 Object.getPrototypeOf() 来获取对象的原型。 prototype 属性是函数的一个特殊属性,指向一个对象。当函数用作构造函数创建实例对象时,该对象的原型会指向构造函数的 prototype 属性指向的对象。也就是说,该对象可以访问构造函数原型对象的属性和方法。 举个例子: ``` function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); } const p = new Person('Tom'); console.log(p.__proto__ === Person.prototype); // true console.log(Person.prototype.constructor === Person); // true console.log(p.constructor === Person); // true ``` 在这个例子,我们定义了一个构造函数 `Person`,并给其原型对象添加了一个 `sayHello` 方法。我们通过 `new` 关键字实例化了一个 `Person` 对象 `p`。这个对象的 `__proto__` 属性指向了 `Person.prototype`,因此我们可以通过 `p.__proto__.sayHello()` 或者 `Person.prototype.sayHello.call(p)` 来调用 `sayHello` 方法。同时,我们也可以通过 `Person.prototype` 来访问 `Person` 构造函数原型对象的属性和方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值