谈谈我对 js原型链的理解
想要学习 “原型链” 必须要认识什么是 “原型” 和 “原型链”
先理解一下普通的继承和原型的区别,下面写一段js代码来帮助理解:
var Animal = function(){ // 动物抽象类
this.name;
this.age;
this.sex;
this.skill = function(){};
this.die = function(){};
};
var Dog = function(){};
var Cat = function(){};
Dog = new Animal(); // 这里Dog就是具体的动物对象 它拥有动物的公有属性 【 name, age, sex, func:sikll, func:die 】
Cat = new Animal(); // 这里Cat也是具体的动物对象 它呢也拥有动物的公有属性【 name, age, sex, func:sikll, func:die 】
Dog 和 Cat 同时继承了 Animal 也就是说他们都拥有 【 name, age, sex, func:sikll, func:die 】这些属性。 那么他们和原型的区别是什么呢?
区别就是:不管是 Dog继承或是Cat继承又或者是其它具体类继承了Animal ,各自都会复制一份 Animal内部的结构(大脑里构建一下这样的场景), 试想一下,如果有几十个上百个具体类继承了Animal 难道还要复制几十个上百个Animal内部结构吗?
那怎么解决上面多复制的问题呢? 那这就是“原型”要解决的问题咯, 对的就是说使用原型后不管有多少个类继承Animal 它内部的结构只复制一次。 够明白了吗? 这就是原型的概念!
我们把上面的代码改动一下,看看原型的写法:
var Animal = function(){ // 动物抽象类
this.name;
this.age;
this.sex;
};
Animal.prototype.skill = function(){};
Animal.prototype.die = function(){};
var Dog = function(){};
var Cat = function(){};
Dog.prototype = new Animal();
Cat.prototype = new Animal();
这样写就可以继承Animal类下的所有字段和方法,但是这里有个小问题,就是说 skill 和 die 可以正常调用,因为他们是函数 。 但是name / age / sex 这三个字段只能读,如果你写 Dog.name = "旺财"; 这样系统会认为name是 Dog下的name 而不是 Animal下的name (这句话如果看不懂等会看原型链就会懂的)。
为什么要说一下这个小问题呢, 因为有很多人认为他们是共享的只要修改了 dog 那么 cat 的name 也会改变, 这里纠正一下哈,以后不要这么认为了。
那么如果只想继承Animal类的原型 而不继承字段应该怎么办呢, 那我们在来改动一下代码:
var Animal = function(){ // 动物抽象类
this.name;
this.age;
this.sex;
};
Animal.prototype.skill = function(){};
Animal.prototype.die = function(){};
var Dog = function(){};
var Cat = function(){};
Dog.prototype = Animal.prototype;
Cat.prototype = Animal.prototype;
是的 Dog.prototype = Animal.prototype; 这样写就可以了,这样就可以有效的屏蔽Animal类的字段了,可以放心的使用它的原型函数了。
那原型链又是一个什么概念呢?其实js的原型链也很好理解我们先来看一个案例
var Animal = function(){ // 动物抽象类
this.name = "二哈";
this.age = "1";
this.sex = "公狗";
};
Animal.prototype.skill = function(){};
Animal.prototype.die = function(){};
var Dog = function(){};
Dog.prototype = new Animal();
Dog.name = "旺财";
Dog.shout = "汪汪汪";
console.log(Dog.name); // 输出的是 旺财 而不是 二哈
console.log(Dog.shout); // 输出的是 汪汪汪
console.log(Dog.sex); // 输出的是公狗
根据这个案例怎么来理解原型链呢? 我们先来看 Dog.name 为什么会输出旺财 而不是二哈呢? 因为js解析时会先找 dog下面是否有name , 如果dog下面没有name就会去 dog的prototype原型里找 name 如果dog.prototype原型里也没有name 就会去object里去找,
如果还找不到那就是没有定义, 那么dog下面有个name 那么 animal下面也有个name js解析的时候会先找到最近的 dog下的name, 所以输出的是 旺财 而不是 二哈
理所当然 Dog.shout 输出的也是 dog下的 shout , 但是 dog 下面没有找到 sex 属性,所以就去 dog.prototype下找到 sex 字段并输出;
理解原型链查找路线图 dog->animal->object 简而言之就是 先找dog下的字段, 再找 animal下的字段, 最后是 object下的字段 这就是原型链的运行轨迹!!!
谈谈我对 js原型链的理解的更多相关文章
- JS原型链的理解和使用(一)
一些个人的理解,不一定是对的,仅供参考. 在JS中有函数和对象两个概念,而又有一切皆对象的概念及函数也是一个对象.所以可以说函数一定可以作为一个对象,而对象不一定是一个函数. 也可以说在js中对象分为 ...
- js原型链结构理解
在一般的面向对象的语言中,都存在类(class)的概念,类就是对象的模板,对象就是类的实例. 但在js中是没有类的定义的(万物皆是对象). 题外话:但是在ES6中提供了更接近传统语言的写法,引入了C ...
- JS原型链的理解和使用(二)
根据在创建对象的时候,创建出来的对象的__proto__指向创建这个对象的函数的prototype属性. 由于在调用对象的属性或者方法的时候会首先在对象的作用域中查找指定的属性或者方法,如果未找到则会 ...
- 分享一个关于js原型链的理解
http://www.cnblogs.com/wyaocn/p/5815761.html
- 深入理解JS原型链与继承
我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...
- 简单粗暴地理解js原型链–js面向对象编程
简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...
- js原型链理解(2)--原型链继承
1.原型链继承 2.constructor stealing(构造借用) 3.组合继承 js中的原型链继承,运用的js原型链中的__proto__. function Super(){ this.se ...
- 深入分析JS原型链以及为什么不能在原型链上使用对象
在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...
- JS 原型链图形详解
JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...
随机推荐
- SQLServer数据库
分离数据库:右键数据库→任务→分离数据库→确定 附加数据库:数据库右键→任务→附加→选择要附加的dlf文件→附加 导出SQL脚本步骤:右键数据库→任务→生成脚本→高级→要编写脚本的数据的类型→架构和数 ...
- my first homepage
<!DOCTYPE html><html><head><style type="text/css">p{ text-indent:2 ...
- python自动生成bean类
近期在学习python,一直在和java做对比,目前没有发现有通过字段自动生成getter setter方法,故此自己写了一个类,可以通过__init__方法传入类名和字段数组,再调用内部的方法,就可 ...
- code about led_shake
//write by:cyt //Project Name:Led on/off //Time:2017-2-10 #include<reg51.h> void delay(int c) ...
- PHP下载微信头像
public function downloadPic($openid='',$headimgurl='') { $header = array( 'User-Agent: Mozilla/5.0 ( ...
- failed to start process with commandline '%LAUNCHER_PATH% %LAUNCHER_ARGS%', ErrorCode = '0x80070002
在dotnet core进行开发的时候,需要开发目录直接iis进行部署,然而启动的时候,报异常,我们查看windows下的应用日志发现有个这样的错误信息 Application 'MACHINE/WE ...
- TabLayout下划线指示器自适应文字宽度
解决方案1: 更新design库到28.0.0-rc01 implementation 'com.android.support:design:28.0.0-rc01' 然后在TabLayout里设置 ...
- C# socket通讯 send方法记录
由于本人是Java入门的开发,在C#开发中遇到的问题,在此记录一下: 1.client端的send方法不管发送出去没发送出去,总是显示发送出去. 查资料得知,send方法是将数据发送到缓存区,并不是直 ...
- css设置文字多余部分显示省略号
如果只显示一行,则可以使用以下方法: overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 如果需要显示多行,在需要设置的元素s ...
- bbs项目学习到的知识点(orm中的extra)
注册 form组件给input 的标签 添加样式类 参见这篇博客(点击) 上传图像 1.解决 一点击图像就会直接打开上传文件的按钮 #这儿利用了 label标签和input的特殊的联动功能 < ...