js学习之原型prototype(一)

1、javascript中的每个引用类型(原生的、和自定义的)都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

A.prototype = new B();

理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方 法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

 1     if (true) {
 2             function baseClass()
 3         {
 4           this.showMsg = function()
 5           {
 6              alert("baseClass::showMsg");   
 7           }
 8         }
 9 
10         function extendClass()
11         {
12             this.hello= function(){alert("子类");}
13         }
14 
15         extendClass.prototype = new baseClass();
16         var instance = new extendClass();
17         instance.showMsg(); 
18         baseClass.prototype=new extendClass();
19         var base=new baseClass();
20         base.hello();
21 
2    if (true) {
            function baseClass()
        {
          this.showMsg = function()
          {
             alert("baseClass::showMsg");   
          }
        }

        function extendClass()
        {
            this.hello= function(){alert("子类");}
        }

        extendClass.prototype = new baseClass();
        var instance = new extendClass();
        instance.showMsg();
        baseClass.prototype=new extendClass();
        var base=new baseClass();
        base.hello();

    }    if (true) {
            function baseClass()
        {
          this.showMsg = function()
          {
             alert("baseClass::showMsg");   
          }
        }

        function extendClass()
        {
            this.hello= function(){alert("子类");}
        }

        extendClass.prototype = new baseClass();
        var instance = new extendClass();
        instance.showMsg();
        baseClass.prototype=new extendClass();
        var base=new baseClass();
        base.hello();

    }    if (true) {
            function baseClass()
        {
          this.showMsg = function()
          {
             alert("baseClass::showMsg");   
          }
        }

        function extendClass()
        {
            this.hello= function(){alert("子类");}
        }

        extendClass.prototype = new baseClass();
        var instance = new extendClass();
        instance.showMsg();
        baseClass.prototype=new extendClass();
        var base=new baseClass();
        base.hello();

    }
    if (true) {
            function baseClass()
        {
          this.showMsg = function()
          {
             alert("baseClass::showMsg");   
          }
        }

        function extendClass()
        {
            this.hello= function(){alert("子类");}
        }

        extendClass.prototype = new baseClass();
        var instance = new extendClass();
        instance.showMsg();
        baseClass.prototype=new extendClass();
        var base=new baseClass();
        base.hello();

    }

2、原型寻找阻断:即先从自己找方法和属性 ,找不到才去原型中去找;找到了就阻断询找:

function baseClass()
{
    this.showMsg = function()
    {
        alert("baseClass::showMsg");   
    }
}

function extendClass()
{
    this.showMsg =function ()
    {
        alert("extendClass::showMsg");
    }
}

extendClass.prototype = new baseClass();
var instance = new extendClass();

instance.showMsg();//显示extendClass::showMsg

 实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。

 

3、

如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?

答案是可以使用call:

extendClass.prototype = new baseClass();
var instance = new extendClass();

var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//显示baseClass::showMsg

 4、在写复杂的 JavaScript 应用之前,充分理解原型链继承的工作方式是每个 JavaScript 程序员必修的功课。 要提防原型链过长带来的性能问题,并知道如何通过缩短原型链来提高性能。 更进一步,绝对不要扩展内置类型的原型,除非是为了和新的 JavaScript 引擎兼容。

5、hasOwnProperty 函数

// 修改Object.prototype
Object.prototype.bar = 1; 
var foo = {goo: undefined};
 
foo.bar; // 1
'bar' in foo; // true
 
foo.hasOwnProperty('bar'); // false
foo.hasOwnProperty('goo'); // true

 JavaScript 不会保护 hasOwnProperty 被非法占用,因此如果一个对象碰巧存在这个属性, 就需要使用外部hasOwnProperty 函数来获取正确的结果。

var foo = {
    hasOwnProperty: function() {
        return false;
    },
    bar: 'Here be dragons'
};
 
foo.hasOwnProperty('bar'); // 总是返回 false
 
// 使用其它对象的 hasOwnProperty,并将其上下为设置为foo
{}.hasOwnProperty.call(foo, 'bar'); // true

 当检查对象上某个属性是否存在时,hasOwnProperty唯一可用的方法。 同时在使用 for in loop 遍历对象时,推荐总是使用 hasOwnProperty 方法, 这将会避免原型对象扩展带来的干扰。

for in 循环

in 操作符一样,for in 循环同样在查找对象属性时遍历原型链上的所有属性。推荐总是使用 hasOwnProperty。不要对代码运行的环境做任何假设,不要假设原生对象是否已经被扩展了

posted @ 2014-11-12 14:42  谷樵  阅读(215)  评论(0编辑  收藏  举报