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

图片描述

code图片描述/code

////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:有没有什么推荐书可以理解与一下的~~~

阅读 3.5k
4 个回答

通过实例的隐式原型__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

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

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,所以他们就都变了
推荐问题
宣传栏