近期由于加入了豚厂工作,需要接手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版)》后所收获。
网友评论