了解JS的原型链和继承
栏目: JavaScript · 发布时间: 5年前
内容简介:当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。1.调用toString方法时,会先在n实例上查找这个属性,没有找到?2.查找n的原型对象,就是Number.prototype(
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
eg1:
var n = new Number(1) n.toString() // "1" 复制代码
1.调用toString方法时,会先在n实例上查找这个属性,没有找到?
2.查找n的原型对象,就是Number.prototype( n.__proto__
), 我们可以看到
eg2:
var n = new Number(1) n.hasOwnProperty('') // "" 复制代码
1.在n实例上没有找到hasOwnProperty方法
2.在n的原型对象上没有找到
3.在n的原型对象的原型对象上继续查找,找到了Object.prototype( n.__proto__.__proto__
)
原型对象和实例的关系
n.__proto__ === Number.prototype 复制代码
n即是Nubmer的实例,也是Object的实例
// 判断一个对象是构造函数的实例我们用instanceof n instanceof Number // true n instanceof Object // true 复制代码
因为所有的对象都是基于Object创建,所有的对象都是Object的实例
理解原型链是非常重要的,特别是在编写复杂的代码时
生成原型链的方式
使用语法结构创建对象:
var obj = {name: 'obj'} // obj继承了Object.prototype的属性 // 原型链: obj ---> Object.prototype ---> null 复制代码
var arr = [1, 2, 3] // arr继承了Array.prototype的属性(forEach) // 原型链:arr ---> Array.prototype ---> Object.prototype ---> null 复制代码
function fun () {return 1} // fun继承了Function.prototype的属性(call.apply) // 原型链:fun ---> Function.prototype ---> Object.prototype ---> null 复制代码
使用构造函数创建对象
function Person () { this.type = [] } Person.prototype.add = function (v) { this.type.push(v) } var p = new Person() // p 拥有了构造函数Person的属性type, 且p.__proto__ = Person.prototype 复制代码
new关键字在这里做了什么?
var p = {}; Person.call(p) //执行Person() this变量指向对象p, p拥有了Person的属性 p.__proto__ = Person.prototype // p继承了Person的原型对象 复制代码
构造函数与普通函数的区别
1.this指向不一样
2.构造函数默认返回实例对象
p.__proto__ === Person.prototype // 返回简单数据类型 function Person () { var a = 1 return a } var p = new Person() // Person var p = Person() // 1 // 返回引用数据类型 function Person () { var a = {name: 'a'} return a } var p = new Person() // {name: 'a'} var p = Person() // {name: 'a'} 复制代码
使用Object.create创建对象
var obj = {name: 'obj'} // obj是个实例对象 // 原型链:obj ---> Object.prototype ---> null var child = Object.create(obj) // 原型链:child ---> obj ---> Object.prototype ---> null 复制代码
object.create的实现方式:
Object.create = function (o) { var F = function () {}; F.prototype = o; return new F(); }; 复制代码
继承方式
原型继承
方式1:
function Person () { this.type = ['good', 'bad'] } Person.prototype.move = function () { console.log('gogogo') } function Child () {} Child.prototype = new Person() var child = new Child() child.move() // gogogo 复制代码
方式2:
var child = Object.create(Person) 复制代码
问题在于原型链中的引用类型,被所有子类实例共享了,我们想要这样嘛? 为什么会这样呢?
var child1 = new Child() var child2 = new Child() child1.type.push('innocent') child2.type // 'good', 'bad', 'innocent' 复制代码
我们先看下原型链: child1 ---> Child.prototype ---> Person.prototype
引用类型type对象是Child.prototype上面的属性, 所以子类的实例的type属性都是指向同一个Child.prototype.type
问题:父类实例的引用对象不共享,子类实例会共享? 因为new关键字
组合继承(构造加原型)
function Person () { this.type = ['good', 'bad'] } Person.prototype.move = function () { console.log('gogogo') } function Child () { Person.call(this) } Child.prototype = new Person() var child = new Child() child.move() // gogogo var child2 = new Child() child.type.push('innocent') child2.type // "good", "bad" 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 构造函数、原型、原型链、继承
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- JavaScript原型链继承
- JavaScript 继承和原型链
- 彻底弄懂JS原型与继承
- 前端进击的巨人(七):走进面向对象,原型与原型链,继承方式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Learning PHP & MySQL中文版
车立红 / 中国电力出版社 / 2007-06 / 36.00元
《Learning PHP & MySQL中文版》将介绍程序、模板和数据库的工作原理,讲述如何应对其中的挑战,并彻底地探索这些技术。一起来看看 《Learning PHP & MySQL中文版》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
HEX CMYK 转换工具
HEX CMYK 互转工具