/* 原型Prototype */ //一、原型 //原型使用一 var calculator = function (dlg, tax) { this.dlg = dlg; this.tax = tax; } calculator.prototype = { add: function (x, y) { return x + y; }, subtrac: function (x, y) { return x - y; } } //原型使用二 //封装私有函数 calculator.prototype = function () { add = function (x, y) { return x + y; }, subtract = function (x, y) { return x - y; } return { add: add, substract: subtract } }(); //分开设置原型的每个属性 calculator.prototype.add = function (x, y) { }; calculator.prototype.substract = function (x, y) { }; var cal = function () { this.tax = 5; }; cal.prototype = new calculator(); //cal的原型指向calculator的实例上,让cal继承两个函数 //无论创建多少个cal实例,都指向同一个对象 var newCal = new cal(); newCal.dlg; //不想访问calculator的构造函数声明的属性值dlg cal.prototype = calculator.prototype; cal.dlg//报错 //重写原型 //覆盖前面的add方法 calculator.prototype.add = function (x, y) { return x + y + this.tax; }; var calc = new calculator(); calc.add(1, 1); //二、原型链 function Foo() { this.value = 42; } Foo.prototype = { method: function () { } }; function bar() { } bar.prototype = new Foo(); bar.prototype.foo = 'hello'; //? bar.prototype.constructor = bar; var test = new bar(); /* 原型链 test[bar实例] bar.prototype [foo实例] {foo:'hello'} foo.prototype {method:...}; Object.prototype {toString:....} */ //属性查找 function foo() { this.add = function (x, y) { return x + y; } } foo.prototype.add = function (x, y) { return x + y + 10; } var f = new foo(); f.add(1, 2) //3, 先找自身属性,再往上找,直到object,如果没有,返回undefined. for in 效率问题 foo.prototype = 1;//错误,不能赋值原子类型的值 //hasOwnProperty函数,唯一一个处理属性不查找原型链的函数 Object.prototype.bar = -1; var foo = { goo: undefined }; 'bar' in foo //true,查找原型链 foo.hasOwnProperty('bar');//false 未查找原型链 foo.hasOwnProperty('goo');//true //hasOwnProperty不受保护,可能会被非法占用命名,需要使用外部的hasOwnProperty来获取正确结果 var foo = { hasOwnProperty: function () { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // 总是返回 false // 使用{}对象的 hasOwnProperty,并将其上下为设置为foo var my = {}; my.hasOwnProperty.call(foo, 'bar');