【JS】关于js高程3上原型的问题

【JS】关于js高程3上原型的问题

【JS】关于js高程3上原型的问题

////test

function Person(name){

this.name = name;

}

Person.prototype.name = 'proto' //设置原型对象的name属性

var person1 = new Person(); //创建实例person1

var person2 = new Person(); //创建实例person2

console.log(Person);// [Function: Person] 方法本身

console.log(Person.prototype.constructor) //[Function: Person] 构造函数Person原型对象的constructor属性

console.log(person1.__proto__); //Person { name: 'proto' } 实例person1的[[prototype]]

console.log(Person.prototype); //Person { name: 'proto' } 构造函数Person原型对象

console.log(Person === Person.prototype.constructor); //true 指向1

console.log(person1.__proto__ === Person.prototype);//true 指向2

console.log(person1.__proto__ === person2.__proto__); //true 无指向

console.log(Object.getPrototypeOf(person1) === Person.prototype) //true 构造函数Person的原型对象 和 实例person1的[[prototype]] (这个不知道这样描述正确不)

person1.__proto__.name = 'modify'; //通过实例的[[prototype]] 改变了person1实例[[prototype]]的name属性

console.log(Person.prototype.name); // modify

console.log(person2.__proto__.name); //modify

var person3 = new Person();

console.log(person3.__proto__.name) //modify

指向1:构造函数Person原型对象的constructor属性指向Person 这一个构造函数, 且2者全等。不能得出如果2个属性全等,则有指向,而书中指向是单向性,为什么?不清楚书中的指针的含义

问题1:
构造函数Person原型对象的constructor属性指向Person 这一个构造函数, 且2者全等。不能得出如果2个属性全等,则有指向,而书中指向是单向性,为什么?

指向2:构造函数person1的[[prototype]]指向Person构造函数的原型对象,在书中有写到 "虽然通过对象实例访问保存在原型的值,但却不能通过对象实例重写原型的值

问题2:
但是在后面输出3个modify中,很明显原构造函数原型的值可以被对象实例person1或者person2修改了,这是为什么??

PS:有没有什么推荐书可以理解与一下的~~~

回答

通过实例的隐式原型__proto__是可以修改构造函数的原型对象(prototype)上的值,因为__proto__跟构造函数的原型对象(prototype)全等( __proto__指向 构造函数的原型对象prototype ),而且__proto__的指向可以被改变

var Createobj = function(){

}

Createobj.prototype.userName = 'ghostwu';

var obj = new Createobj();

console.log( obj.userName ); //ghostwu

obj.__proto__.userName = 'abc';

console.log( obj.userName ); //abc

var obj2 = new Createobj();

console.log( obj2.userName ); //abc

不嫌弃的话,可以看看我之前写的这篇总结。点击跳转

第一个问题没看懂你说的啥。
第二个问题:
书上所说实例访问是这样的:personal2.name,这样访问的话由于name是原型继承来的,所以它不是personal2本身的,如果你personal2.name=modify这样修改的话,相当于给personal2.name自身添加属性,不影响原型里的。这也就是原型链里的说的,先访问自己的,自己没有,再访原型的。
而personal2.__proto__.name,这样访问的话是指接访问原型对象的,跟Personal.prototype.name效果一样。而且有的浏览器好像不实现此__proto__属性,都不建议使用。毕竟不希望每个实例都可以修改原型对象。

我看javascript权威指南、javascript高级程序设计等,反正有关的都看看,共同学习。

nice question! 既然已经了解到这儿了,不妨再看一本书《你不知道的javascript》。小红书更多得是让人学会怎么用js,你不知道的js就是在揭js的老底了。你问的问题我觉得都是小红书想回避的问题。__proto__虽然没被列为标准,但现代浏览器基本都实现了他的功能,所以我觉得你提出的问题是书里有所隐瞒。实际项目里虽然不会去用这个属性,但不代表我们不需要知道这些东西。

  1. 图中的指向只是实际所在的位置。假如函数Fun被存在内存中0x0001位置,那么Fun.prototype.constructor的地址也是0x0001,并不是说是一个单向的关系。好比,我家在人民路01号,你有一个属性是我家的位置,你使用这个位置的时候就会被直接导向人民路01号。这应该是书里前面的存值与存址的概念,包括指向2也是这个意思。
  2. 同理。person2.__proto__存的是Person.prototype对象的地址,改person2.__proto__直接就导向了Person.prototype,所以你改的就是构造函数的原型,而不是实例本身,所以不符合通过修改实例修改了构造函数原型这一结论。


补充评论里的一些东西:
其中LHS和RHS参考
前面有点不严谨的地方,应该类似于

var a = {key: 'a'}

// 内存里一块区域0x0001存下了{key: 'a'}

// a -->0x0001

var b = a

// RHS查到a地址为0x0001,拿到该地址并

// b -->0x0001

var c = {key: 'c'}

// 内存里一块区域0x0002存下了{key: 'c'}

b = c

// RHS查到c地址为0x0002,拿到该地址并

// b -->0x0002

// 但是a还是指向0x0001

//如果这么改

c.key = 'new'

// 找到c为内存中0x0002,将其中key改为'new'

// 又因为b和c现在都指向0x0002,所以他们就都变了

以上是 【JS】关于js高程3上原型的问题 的全部内容, 来源链接: utcz.com/a/90023.html

回到顶部