扫码关注官方订阅号
请看代码
代码一
代码二
为什么结果是相反的?
JavaScript中基于原型链的继承是怎么样的?
光阴似箭催人老,日月如移越少年。
__proto__ 是实例(如 tidy)访问原型对象,同时它是非标准的,ES5 标准方法是 Object.getPrototypeOf()prototype 是构造函数(如 Dog) 访问原型对象
__proto__
Object.getPrototypeOf()
prototype
可以这样验证
function Dog() {} var tidy = new Dog(); // 它们引用的是同一个内存地址,即它们的原型。 tidy.__proto__ === Dog.prototype
但是到这里并没有体现基于原型链的继承
function Dog() {} function Animal() {} // 实现原型链继承 Dog.prototype.__proto__ = Animal.prototype; var tidy = new Dog(); // tidy 的原型指向 Dog.prototype tidy.__proto__ === Dog.prototype // 因为 Dog.prototype.__proto__ === Animal.prototype // tidy 的原型的原型(形成原型链)指向 Animal.prototype tidy.__proto__.__proto__ === Animal.prototype // 原型链的终端是 Object.prototype tidy.__proto__.__proto__.__proto__ === Object.prototype // 再往前就是 null 了 tidy.__proto__.__proto__.__proto__.__proto__ === null
又有人问这个问题了,__proto__本质上其实是标准里规定的[[prototype]]属性,原本是不可用 js 访问的,后来(据说标准里又规定可以)firefox 和 chrome 中把这个属性命名为__proto__。后来ES又添加了函数getPrototypeof,这样就可以通过这个函数来访问这个属性,所以这个__proto__现在不是标准的一部分。
[[prototype]]
ES
getPrototypeof
然后,再说new的创建过程,当执行new func()的时候,执行过程如下:1、首先创建一个新的对象,比如叫 obj;2、obj.[[prototype]] = func.prototype;3、令this=obj,执行函数 func;4、如果 func 的返回值是一个对象,则 new 的返回值就是这个对象,否则返回值是 obj
new
new func()
obj
obj.[[prototype]] = func.prototype
this=obj
func
当 __读取__(注意是读取)对象的属性的时候,返回值是:
if(obj.prop) return obj.prop else if(obj.[[prototype]].prop) return obj.[[prototype]].prop; else if(obj.[[prototype]].[[prototype]].prop) return obj.[[prototype]].[[prototype]].prop; //......一直这样找下去 else { return undefined;}
如下图:
var Fish = new Function(){} //等价于 var Fish = function(){}
根据上面大神的解释,我总结了一下,作用域链的指向如下
以下代码可以直接运行,大家可以试一下
<script type="text/javascript"> var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.__proto__ = animal; var tidy = new dog(); console.log(dog.__proto__ === animal) //true console.log(dog.__proto__.__proto__ === animal.__proto__) //true console.log(dog.__proto__.__proto__.__proto__ === Object.prototype) //true console.log(dog.__proto__.__proto__.__proto__.__proto__ === null) //true console.log(tidy.__proto__ === dog.prototype) //true console.log(tidy.__proto__.__proto__ === dog.prototype.__proto__) //true console.log(tidy.__proto__.__proto__ === Object.prototype) //true console.log(tidy.__proto__.__proto__.__proto__ === null) //true console.log(dog.price) //2000 console.log(tidy.price) // undefined </script>
<script type="text/javascript"> var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.prototype = animal; var tidy = new dog(); console.log(tidy.__proto__ === dog.prototype) //true console.log(tidy.__proto__.__proto__ === animal.__proto__) //true console.log(tidy.__proto__.__proto__.__proto__ === Object.prototype) //true console.log(tidy.__proto__.__proto__.__proto__.__proto__ === null) //true console.log(dog.__proto__ === Function.prototype) //true console.log(dog.__proto__.__proto__ === Object.prototype) //true console.log(dog.__proto__.__proto__.__proto__ === null) //true console.log(dog.price) //undefined console.log(tidy.price) // 2000 </script>
tidy是对象,而dog是function。可以这么理解,prototye指定类型(函数)基类,而__proto__获得对象的原型链
function 拾人牙慧(){//我觉得重点在于理解下面这段语句:var tidy = new dog();//即tidy.__proto__ === dog.prototype;}
另外dog.prototype = animal; 是不会影响原dog()函数中的属性。而dog.__proto__指向了animal,所以dog.price继承了animal.price不知道理解是否得当,有错误请指出。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
__proto__是实例(如 tidy)访问原型对象,同时它是非标准的,ES5 标准方法是Object.getPrototypeOf()prototype是构造函数(如 Dog) 访问原型对象可以这样验证
但是到这里并没有体现基于原型链的继承
又有人问这个问题了,
__proto__本质上其实是标准里规定的[[prototype]]属性,原本是不可用 js 访问的,后来(据说标准里又规定可以)firefox 和 chrome 中把这个属性命名为__proto__。后来ES又添加了函数getPrototypeof,这样就可以通过这个函数来访问这个属性,所以这个__proto__现在不是标准的一部分。然后,再说
new的创建过程,当执行new func()的时候,执行过程如下:1、首先创建一个新的对象,比如叫
obj;2、
obj.[[prototype]] = func.prototype;3、令
this=obj,执行函数func;4、如果
func的返回值是一个对象,则new的返回值就是这个对象,否则返回值是obj当 __读取__(注意是读取)对象的属性的时候,返回值是:
如下图:
根据上面大神的解释,我总结了一下,作用域链的指向如下
以下代码可以直接运行,大家可以试一下
代码一
代码二
tidy是对象,而dog是function。可以这么理解,prototye指定类型(函数)基类,而__proto__获得对象的原型链
function 拾人牙慧(){
//我觉得重点在于理解下面这段语句:
var tidy = new dog();
//即
tidy.__proto__ === dog.prototype;
}
另外dog.prototype = animal; 是不会影响原dog()函数中的属性。
而dog.__proto__指向了animal,所以dog.price继承了animal.price
不知道理解是否得当,有错误请指出。