原型prototype -- 深入理解javascript

/*
    原型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');