原型的使用
//构造函数 定义实例属性 //原型定义 方法和共享属性 function Ka(name, age) { this.name = name; this.age = age; this.child = [1, 2, 3, 4]; } Ka.prototype = { constructor: Ka, say: function() { console.log(this.name); } }
按需加载原型
//不把构造函数和原型写到一起 //根据需要定义原型 function Ka(name, age) { this.name = name; this.age = age; this.child = [1, 2, 3, 4]; //只有say方法不存在时才添加到原型中 if(typeof this.say != "function") { Ka.prototype.say = function() { console.log(this.name); } } } var k1 = new Ka("1号", 18); k1.say(); //1号
原型链实现继承
//原理 a(实例对象) 有 A(原型对象)的所有方法属性,a有constructor属性指向A //把a赋值给原型对象B B中就有constructor 指向A 实例对象b就有原型A中的方法 function A(x) { this.x = x; } A.prototype.say = function() { console.log(this.x); } A.prototype.age = 10; var a = new A(1); function B(x, y) { this.x = x; this.y = y; } console.log(a.age); //10 a.say(); //1 a原型中的方法 B.prototype = a; var b = new B(2, 3); b.say(); //2 先看实例(b)的再看原型的(a) 所以是2 console.log(b.age); //10 继承了a原型中的方法 console.log(b.y); //3 //说白了就是从新给B的原型附一个对象
寄生构造函数
//构造函数只是返回一个与自己无关的拿走了自己参数的对象 没有拿走原型上的方法 function Ka(name, age) { var o = new Object(); o.name = name; o.age = age; o.say = function() { console.log(this.name); } return o; //返回o 把this指向o } Ka.prototype.aa = "aa"; var k1 =Ka("1号", 18); //都不用new 因为自己返回了一个对象 k1.say(); //1号 console.log(k1.aa); //undefined 没有拿到原型上的方法 //k1的原型的构造函数是Ka吗 console.log(k1.__proto__.constructor == Ka); //false
稳妥构造函数
//所谓稳妥是指没有公共属性,而且其方法也不引用this的对象。 //一是新创建对象的实例方法不引用this,二是不使用new操作符调用构造函数。 //与寄生类似 //问题1 稳妥 哪里稳妥了 //正常的 function ku(name,age){ this.name=name; this.age=age; this.say=function(){ console.log(this.name); } } let k1=new ku("王二",15); k1.say=function(){ console.log(this.age); } k1.say(); //15 方法被修改了 因为有this 很好改
//稳妥的 function Ka(name, age){ var name=name; var age=age; var o = new Object(); o.say=function(){ console.log(name); }; o.modify=function(){ name="aa"; }; return o; } let a1=new Ka("王二",15); a1.say(); //王二 a1.modify(); //通过返回的方法 可以修改私有变量 a1.say(); //aa a1.say=function(){ console.log(this.age); }; a1.say(); //undefined 自己添加的方法不能访问内部私有变量 //什么是私有变量 //私有变量包括函数的参数、局部变量和在函数内部定义的其他函数。 //稳妥构造函数的意义 //不可以通过为函数添加方法来访问、修改函数的内部数据。