内容简介:关于我的疑问?为什么要用构造函数,用构造函数有什么好处?一直没有找到合适的答案,最后终于在红宝书中找到了线索!工厂模式创建的‘人’是没有灵魂的,因为他们不能识别创建他们的‘爸爸’,也就是alert(person1 instanceof createPerson);//false 这是因为o对象在createPerson函数中重新new Object()了,所以createPerson不是o的原型了而构造函数模式就解决了这个问题
关于我的疑问?为什么要用构造函数,用构造函数有什么好处?一直没有找到合适的答案,最后终于在红宝书中找到了线索!
function createPerson(name,age,sex){ var o = {}; o.name = name; o.age = age; o.sex = sex; o.sayName = function(){ alert(this.name) } } var person1 = createPerson('小明',18,'女'); var person2 = createPerson('小西',20,'男'); 复制代码
工厂模式创建的‘人’是没有灵魂的,因为他们不能识别创建他们的‘爸爸’,也就是alert(person1 instanceof createPerson);//false 这是因为o对象在createPerson函数中重新new Object()了,所以createPerson不是o的原型了
而构造函数模式就解决了这个问题
二、构造函数模式
function Person(name,age,sex){ this.name = name; this.age = age; this.sex = sex; this.sayName = function(){ alert(this.name) } } var person1 = new Person('小明',18,'女'); var person2 = new Person('小西',20,'男'); 复制代码
用这种new的方法创建出来的对象会自动获得一个constructor(构造函数)属性,这个属性,指向它的‘爸爸’,也就是Person。
构造函数虽然好用,但有一个缺点就是,在创建实例对象的时候,会把方法重新创建一遍。这会导致不同的作用域和标识符。alert(person1.sayName == person2.sayName)//false
** 解决办法:**
function Person(name,age,sex){ this.name = name; this.age = age; this.sex = sex; this.sayName = sayName } function sayName(){ alert(this.name) } var person1 = new Person('小明',18,'女'); var person2 = new Person('小西',20,'男'); 复制代码
把sayName函数作为全局函数,有一个指向函数Person的指针,person1和person2就可以访问同一个方法了。但这又会有一个新问题,sayName函数放在全局中,就能被其他对象调用,这是不太合理的,且不适用于封装。
这时候,原型模式就要登场了!
三、原型模式
在这个话题开始之前,我们应该先了解一下,property(原型):
了解property
1、每个函数都有property(原型)
2、每个对象都有_proto_(隐式原型)
3、对象是属性的集合,函数也是对象,所以函数既有property,又有_proto_
** 那么,prototy到底是什么呢?**
简单来说就是,把属性和方法添加到property(原型)上去,儿子们就可以通过一条线找到这些属性和方法,实现共享
function Person(){ } Person.prototype.name = '小明'; Person.prototype.age = 18; Person.prototype.sex = '女'; Person.prototype.sayName = function(){ alert(this.name) }; var person1 = new Person(); person1.sayName()//小明 var person2 = new Person(); //person2.sayName()//小明 复制代码
** 为什么‘儿子们’可以找到共享的方法呢? **
当创建一个函数爸爸的时候,会给爸爸一个prototype(原型)属性,这个属性会有一个constructor(自动得到的),这个属性会指向函数爸爸。也就是Person.prototype.constructo 指向 Person。
当创建了一个对象实例的时候,这个实例就会有一个_proto_(隐式原型),指向函数爸爸的prototype(原型)。这样说可能有点抽象,或许我们可以上个图!
- Person.prototype指向原型对象
- Person.prototype.constructor指回构造函数Person
- person1和person2都有一个属性,指向原型对象
- Person.prototype == person1(person2). proto
所以实现共享的本质是:当读取对象的属性时,1、看对象自己有没有这个属性或方法,如果找到了,就返回这个值 2、自己没有的话,就通 过_proto_ 指向的 prototype查找有没有这个属性或方法,如果有,就返回。
顺便附上作图工具:www.processon.com/
** 原型模式的缺点 **
- 不能自定义参数
- 属性是共享的,会对包含引用类型的值来说,产生致命问题
function Person(){} Person.prototype={ constructor : Person, name : '小明', age : 18, sex : '男', friends ; ["小花","小夏"], sayName : function(){ alert(this.name) } } var person1 = new Person(); var person2 = new Person(); person1.friends.push(“小天”); console.log(person1.friends);//"小花","小夏",“小天” console.log(person2.friends);//"小花","小夏",“小天” 复制代码
由于person1修改的是Person.prototype,这个共享的属性,所以person2的值也会受影响
四、构造函数模式+原型模式
这种方法才是最目前运用最广泛的方法,因为这种方法取两种模式的有点,构造函数不共享,就用来定义实例的属性,原型模式共享,就用来定义实例的方法。
function Person(name,age,sex){ this.name = name; this.age = age; this. sex = sex; this.friends = ["小花","小夏"]; } var person1 = new Person('小明',18,'女'); var person2 = new Person('小西',20,'男'); person1.push("小天"); console.log(person1.friends);//"小花","小夏",“小天” console.log(person2.friends);//"小花","小夏" 复制代码
以上所述就是小编给大家介绍的《创建对象的藏宝线索》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 技术入门 | 以Transaction的生命周期为线索剖析Libra核心组件
- 日本最大银行:已掌握Zaif交易所6000万美元黑客案线索
- 一个经验性探索:CNN是靠什么线索学习到深度信息的?
- OC对象的本质 实例对象,类对象,元类对象
- 可迭代对象,迭代器(对象),生成器(对象)
- 重学前端学习笔记(七)--JavaScript对象:面向对象还是基于对象?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机程序设计艺术・卷3
[美] 高德纳(Donald E. Knuth) / 贾洪峰 / 人民邮电出版社 / 2017-2 / 198.00元
《计算机程序设计艺术》系列被公认为计算机科学领域的权威之作,深入阐述了程序设计理论,对计算机领域的发展有着极为深远的影响。本书为该系列的第3卷,全面讲述了排序和查找算法。书中扩展了卷1中数据结构的处理方法,并对各种算法的效率进行了大量的分析。一起来看看 《计算机程序设计艺术・卷3》 这本书的介绍吧!