Comments (1)
原型链
想要理解原型链,先要了解什么是原型
一、原型模式
我们创建的每个函数都有一个==prototype==(原型)属性,prototype属性指向原型对象。通过该函数创建的实例对象会共享原型对象上的所有属性和方法。
function Person(){
}
Person.prototype.name = 'test';
Person.prototype.age = 25;
Person.prototype.sayName = function(){
console.log(this.name);
}
const person1 = new Person();
person1.sayName(); //'test'
const person2 = new Person();
person2.sayName(); //'test'
console.log(person1.sayName === person2.sayName); //true
二、原型对象
- 理解原型对象
只要创建了一个函数,就会为该函数生成一个==prototype==属性(指向函数的原型对象)。默认情况下,原型对象会自动获得一个==constructor==属性(构造函数属性),这个属性包含一个指向prototype属性所在函数的指针。当调用该函数创建一个实例后,该实例内部将包含一个指针[[Prototype]](内部属性),指向构造函数的原型对象。虽然在脚本中没有标准的方式访问[[Prototype]],但Firefox、Safari和Chrome在每个对象上都支持一个属性__proto__。而在其他实现中,这个属性对脚本则是完全不可见的。
虽然在所有实现中都无法访问到[[Prototype]],但可以通过==isPrototypeOf==方法来确定对象之间是否存在这种关系。如果[[Prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype),那么这个方法就返回true。
Person.prototype.isPrototypeOf(person1); //true
Person.prototype.isPrototypeOf(person2); //true
==Object.getPrototypeOf==方法可以返回[[Prototype]]的值。例如:
Object.getPrototypeOf(person1) === Person.prototype // true
Object.getPrototypeOf(person1).name // "test"
每当读取对象的某个属性时,都会首先从对象实例本身开始搜索,如果没有则继续搜索原型对象中的属性。虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。
person1.name = "Greg";
console.log(person1.name); // "Greg" 来自实例本身
console.log(person2.name); // "test" 来自原型对象
==hasOwnProperty==方法可以检测一个属性是存在于实例中,还是存在于原型中(从Object继承来的),只在给定属性存在于对象实例中时,才会返回true。
person1.hasOwnProperty("name"); //true
person2.hasOwnProperty("name"); //false
delete person1.name;
person1.hasOwnProperty("name"); //false
- 原型与in操作符
单独使用in操作符时,无论属性存在于实例中还是原型中,只要能访问到给定属性都返回true。
person1.hasOwnProperty('name'); //false
'name' in person1; //true
person2.hasOwnProperty('name'); //false
'name' in person2; //true
person1.name = 'ohyes';
person1.name; // 'ohyes'
person1.hasOwnProperty('name'); //true
'name' in person1; //true
//通过使用hasOwnProperty方法和in操作符可以确定属性是存在于实例中还是原型中
function hasPrototypeProperty(obj,name){
return !obj.hasOwnProperty(name) && name in obj;
}
//属性存在于实例中,返回false;存在于原型中返回true
for - in循环,能够返回对象中所有可枚举的属性,无论存在于实例中还是原型中。屏蔽了原型中不可枚举属性的实例属性也可以在for-in循环中返回。但是在IE8以及更早版本有bug,即屏蔽不可枚举属性的实例属性不会出现在for-in 循环中。
要取得对象上所有可枚举的实例属性,可以使用Object.keys()方法。
Object.keys(Person.prototype); // ["name", "age", "sayName"]
Object.keys(person1); // ["name"]
如果想要得到所有的实例属性,无论是否可枚举,可以使用Object.getOwnPropertyNames()方法
Object.getOwnPropertyNames(Person.prototype); // ["constructor", "name", "age", "sayName"]
- 原型对象的问题
原型中所有属性是被很多实例共享的。对于包含引用类型值的属性的原型对象,会有特别的问题。
//在实例中修改了原型上的引用类型的属性,会在所有实例上反映出来
Person.prototype.friends = ['one', 'two'];
person1.friends.push('three');
person1.friends; // ["one", "two", "three"]
person2.friends; // ["one", "two", "three"]
person2.friends === person1.friends; // true
三、原型链
原型链是实现继承的主要方法。其基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。每个构造函数都有一个prototype属性,指向原型对象。原型对象都包含一个指向构造函数的指针(constructor)。把构造函数的prototype属性修改成另一个构造函数的实例,此时原型对象就将包含指向另一个原型的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是原型链的概念。
//修改构造函数的prototype属性指向另一个构造函数的实例,实现继承
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
this.subproperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subproperty;
}
let instance = new SubType();
console.log(instance.getSuperValue()); //true
from my-blog.
Related Issues (20)
- 专题8: 设计模式之装饰器模式
- 专题9: 发布订阅者模式
- 专题10: js 是如何引用 css 的?
- 专题11: 将js/css打包进html,并配置 devServer
- 专题12: 配置loader如:ts、babel、less|sass
- 专题13: webpack性能优化上(Code Splitting、Tree Shaking)
- 专题14: 手写一个loader,实现一个可选链(obj?.foo?.bar)
- 专题15: webpack性能优化2 (happypack、dllplugin、cache-loader)
- 专题16: webpack之多页面配置
- 专题17: 手写一个webpack插件
- 专题18: webpack 搭建 ssr
- 专题19: vue-next 项目搭建
- 专题20: vue3 响应式原理
- 合并两个有序数组为一个有序数组
- 浏览器跟node的 event loop 区别
- Webpack原理—编写Loader和Plugin
- TCP四次挥手
- 什么是CDN,对SEO优化有什么帮助
- js异步加载(defer、async、module)和预加载(preload、prefetch、subresource、prerender)前端文件
- 2019面经文
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from my-blog.