function Person(name) = { this.name = name this.friends = ["a", "b"] } person.prototype = { constructor: Person, sayName: function() { alert("this.name") } } var p1 = new Person("hi")
但是这很让人困惑。因为构造函数和原型模式单独书写。不符合面向对象的封装。
//因为构造函数会初始化原型,所以原型模式不能书写到构造函数中,因为这样每创建一次实例都会重新定义一下原型函数
所有的都封装在构造函数中,通过在构造函数中初始化原型(仅在必要的时候。就是可以添加一个判断)
function Person(name) = { //属性 this.name = name this.friends = ["a", "b"] //方法 if (typeof this.sayName != "function") { person.prototype.sayName =function() { alert(this.name); } } } var p1 = new Person("hi")
这段代码只会在初次调用构造函数的时候才会执行,此后原型已经完成了初始化。这里在原型中做的修改,能够立即体现在所有的实例中。
原型的动态性:我们对原型对象所做的任何修改,都能够立即从实例上反应出来
总结
function SpecialArray(){ //创建数组 var vlaues = new Array(); //添加值 vlaues.push.apply(values, arguments); //添加方法 values.toPipedString = function(){ return this.join("|"); }; //返回数组 return values; } var colors = new SpecialArray("red", "blue", "green"); alert(colors.toPipedString()); //"red|blue|green"
寄生构造函数模式的目的是实现在不改变原有构造函数的前提下为构造函数添加特殊的方法,这个构造函数的功能就是传入参数,生成一个数组对象,并且这个数组自带SpetialArray方法,而且返回的对象跟构造函数和构造函数的原型对象没有什么关系;
这里演示的是附带special方法, 下次附带数组不具有的方法呢?所以不必纠结join;
为什么没有使用原型方法,开篇就提到了,不改变原有构造函数的前提下,添加新方法,你修改了Array的prototype,所有Array实例都会继承这样一个方法,得不偿失;
比如遇到某个场景:你想创建一个字符串,String字符串自带某种方法可以返回一段复合要求的字符串,你不能直接在String原型上定义该方法,因为这样所有的字符串都会继承这个方法没有必要,但是你又不想每次都调用封装的函数,寄生构造函数就能派上用场了,在创建对象的时候就给这个字符串赋予了你需要调用的方法,同时有不影响String这个全局构造函数
是这样的,Array想要把argements全部push的话,必须要遍历arguments,arguments只是类似数组,但事实上是一个对象,所以push arguments返回的是一个包含单个对象的长度为1的数组,apply把数组的push方法施加到一个数组上,接收的第二个参数是一个数组,所以直接跳过遍历,一次性全部push了
寄生构造函数专门用来为js原生的构造函数定义新的方法
function SpecialArray(){ var values = new Array(); values.push.apply(values, arguments); values.toPipedString = function(){ return this.join("|"); } return values; } var a = new SpecialArray(2,6,8,9,4); a.toPipedString(); var b = SpecialArray(2,6,8,9,4); b.toPipedString();
寄生构造函数模式和工厂模式没有本质区别,通过new 操作符的就叫寄生构造函数模式,直接调用的就叫工厂模式
JS里的构造函数就是一个用来构造对象的普通函数,和JAVA不同
你要知道,通过new 来调用函数,会自动执行下面操作
创建一个全新的对象
这个对象会被执行[[prototype]]连接原型
函数调用中的this会绑定到新对象
如果函数没有返回其他对象,那么new 构造就会自动返回这个新对象
由于这里new调用和直接调用都返回values,所以a,b引用的数组对象是一样的
原文:https://www.cnblogs.com/-constructor/p/11870870.html