《JavaScript中原型链的理解》

近期由于加入了豚厂工作,需要接手ReactNative的项目,所以我接触一些JavaScript知识,这篇文章和大家分享下原型链的知识。

原型的概念
原型链的概念、使用
一、创建对象的方式

1.通过Object构造函数
var person = new Object();
person.name = “Jesse";
person.age = 26;
person.job = ”iOS Engineer";
person.sayName = function(){ alert(this.name);};

2.通过字面量创建对象

var person = { name : "Stephen Curry", age : 30, job : "basketball player", sayName :function () { alert(this.name); }}
以上两种方式创建对象的弊端:
当需要创建很多有相同属性或者方法的相似对象时,需要些大量多余、重复的代码

3.通过工厂模式创建对象
function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; 解决了前两种创建相似对象, o.sayName = function(){ 很多重复代码的问题 alert(this.name); }; return o;}
var person1 = createPerson(”Jesse",26, ”iOS Engineer");
var person2 = createPerson(” Stephen Curry ",30, "basketball player”);
var person3 = …………..
var person4 = …………..

通过Object构造函数与工厂模式对比
var person = new Object();person.name = “Jesse";person.age = 26;person.job = ”iOS Engineer";person.sayName = function(){ alert(this.name);};
通过Object构造函数与工厂模式对比结论:
优点:工厂模式创建多个相似对象时,代码量比较少
缺点:无法直接得出创建出来的实例是哪种类型

4.通过自定义的构造函数创建对象
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; }
var person1 = new Person(”Jesse",26, ”iOS Engineer");
var person2 = new Person(” Stephen Curry ",30, "basketball player”);

自定义构造函数的关键
new FunctionName()创建新对象
将构造函数的作用域赋给新对象,This指向新对象
执行构造函数中的代码,返回新对象

自定义构造函数的弊端
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; }
var person1 = new Person(”Jesse",26, ”iOS Engineer");
person1.sayName();
var person2 = new Person(” Stephen Curry ",30, "basketball player”);
person2.sayName();

二、原型模式
原型对象
原型链

1.原型对象的定义
function Person(){}Person.prototype.name = ”Jesse";Person.prototype.age = 26;Person.prototype.job = ”iOS Engineer";Person.prototype.sayName = function(){ alert(this.name);};var person1 = new Person();person1.sayName(); //" Jesse "var person2 = new Person();person2.sayName(); //" Jesse "

原型对象的定义:
我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,即原型对象。
Person.prototype.name = ”Jesse“; Person.prototype就代表原型对象。

原型对象的作用:
可以让所有对象实例共享它所包含的属性和方法。
person1.sayName(); //" Jesse ”
person2.sayName(); //" Jesse "
person1.sayName == person2.sayName
这里也解决了自定义构造函数,做同一件事,却实例化两个不同对象的问题

function Person(){}
Person.prototype.name = ”Jesse";Person.prototype.age = 26;Person.prototype.job = ”iOS Engineer";Person.prototype.sayName = function(){ alert(this.name);};
var person1 = new Person();person1.sayName();
答案:如果没有如果,后来也没有后来
function Person(){}Person.prototype.name = ”Jesse“;Person.prototype.age = 26;Person.prototype.job = ”iOS Engineer“;Person.prototype.sayName = function(){ alert(this.name);}; var person1 = new Person();var person2 = new Person();person1.name = ” Stephen Curry “;alert(person1.name); // ” Stephen Curry “; alert(person2.name); // ”Jesse“;

2、原型的动态性

1.Person.prototype = { constructor: Person, name : ”Jesse“, age : 26, sayName : function () { alert(this.name); }};
2.var friend = new Person();
3.Person.prototype.sayHi = function(){ alert(”hi“);};
4.friend.sayHi();//”hi”

function Person(){}
//创建构造函数时,会有一个原型var friend = new Person();
//此时等于重写了一个新的原型Person.prototype = { constructor: Person, name : ”Jesse“, age : 29, job : ”iOS Engineer", sayName : function () { alert(this.name); }};
friend.sayName(); //error ,friend指向的原型不包含sayName

3.使用原型创建对象的问题

function Person(){} Person.prototype = { constructor: Person, name : ” Stephen Curry “, age : 26, job : ”iOS Engineer", friends : [”KD", " Thompson "], sayName : function () { alert(this.name); }};

问题
所有的实例默认情况下取得相同的属性值
类似Array这种引用类型的属性来说,达不到预期的效果

4.组合使用构造函数和原型模式
构造函数来定义那些实例属性,原型模式定义方法和共享属性
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"];}Person.prototype = { constructor: Person, sayName : function () { alert(this.name); }}; var person1 = new Person(”Jesse",26, ”iOS Engineer");
var person2 = new Person(” Stephen Curry ",30, "basketball player”);
三、原型链
认识和使用原型链

严格来说, JavaScript是一种基于对象的语言,
在Js中无法实现接口继承,但可以支持实现继承
JS中的继承使用的就是原型链

1、认识原型链
原型对象等于另一个类型的实例
原型对象将半含指向另一个原型的指针[[Prototype]]
另一个原型中也包含着一整个指向另一个构造函数的指针constructor
依次往下继续,则会行程一条链,即原型链
2.实现一个原型链
function SuperType(){ this.property = true;}SuperType.prototype.getSuperValue = function(){ return this.property;};

3.原型链的问题
function SuperType(){ this.colors = [“red”, “blue”, “green”]; }function SubType(){ }SubType.prototype = new SuperType();var instance1 = new SubType();instance1.colors.push("black");alert(instance1.colors); //"red,blue,green,black"var instance2 = new SubType();alert(instance2.colors); //"red,blue,green,black"
3.组合继承
实现原理:
使用原型链实现对原型属性和方法的继承,
通过借用构造函数实现对实例属性继承

每个函数都包含call()和apply()方法
这个两个方法都是在特定的作用域中调用函数

function SuperType(name){ this.name = name; this.colors = [“red”, “blue”, “green”];}SuperType.prototype.sayName = function(){ alert(this.name);};function SubType(name, age){ SuperType.call(this, name); //构造函数实现实例属性继承 this.age = age;}SubType.prototype = new SuperType();//原型链实现方法的继承SubType.prototype.sayAge = function(){ alert(this.age);};

var instance1 = new SubType(”Jesse", 26);instance1.colors.push("black");alert(instance1.colors); //"red,blue,green,black"instance1.sayName(); //”Jesse";instance1.sayAge(); //26var instance2 = new SubType("Greg", 27);alert(instance2.colors); //"red,blue,green"instance2.sayName(); //"Greg";instance2.sayAge();
实现了继承,instance1修改colors属性也不会影响instance2
四、总结
1.创建对象的种方法
通过Object构造函数
通过字面量创建对象
通过工厂模式创建对象
通过自定义的构造函数创建对象
2.原型
我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,即原型对象
组合使用构造函数和原型模式, 构造函数来定义那些实例属性,原型模式定义方法和共享属性
3.原型链
原型对象等于另一个类型的实例
组合继承:使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性继承

以上知识点主要是读《JavaScript高级程序设计(第3版)》后所收获。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容