`

对JavaScript对象原型的理解

阅读更多

文章转自:http://www.iebe.cn/blog/article.asp?id=93

 

好多学习JS的人都很难理解JavaScript的原型是个什么东东,下面就跟着我的文字,让我来带领大家解开JavaScript原型的神秘面纱。

    第一。先看如下函数

function createPerson(name,sex,birthday) {   
        //通过参数传递赋予函数对象值
        this.name = name ;
        this.sex = sex;
        this.birthday = birthday;
        this.sayHi = function(){
        alert(this.name+"is saying hello to everyone.");
        }; 
      return this;   
}    
 

 

上面函数通过定义Function类createPerson来创建一个人,并赋予人的姓名,性别,生日和说话的属性,切记,在JS中,这不同于其他的面向对象编程语言的地方,JS是没有方法这一说法。
然后,我们来创建一个人名叫Rose,定义如下

      var rose = new createPerson('Rose ','female','1985-01-01');

     这样子,我们就可以直接通过rose对象去直接访问rose具有的属性了。如rose.name,rose.sex,对于sayHi,相对特殊,因为 rose的sayHi是一个函数,所以对于sayHi的调用,就像一般的函数调用一样,rose.sayHi();

      可能你会觉得,这样子写不是好完美了吗?的确,如果在其他面向对象编程语言中,类似于这样子的写法的确是完美了,但是对于JS却有一个重要的特性,就是原 型。要理解原型,还得从分析var rose = new createPerson('Rose ','female','1985-01-01');这代码入手。这段代码执行过程大概如下,

  第一步是建立一个新对象-rose

  第二步将该对象内置的原型对象设置为构造函数prototype引用的那个原型对象,也就是因为JS每个函数,都具有原型对象如 (createPeson.prototype)。这就是说rose对象的原型对象设置为构造函数createPeson.prototype

  第三步就是将该对象作为this参数调用构造函数,完成成员设置等初始化工作。 换句话说就是   

functon createPerson(name,sex,birthday) {   

             this.name = name ;
             this.sex = sex;
            this.birthday = birthday;
            this.sayHi = function(){
         alert(this.name+"is saying hello to everyone.");
          }; 
      return this;   
}    被替换成如下的调用形式,

functon createPerson(name,sex,birthday) {   

             rose.name = name ;
             rose.sex = sex;
             rose.birthday = birthday;
             rose.sayHi = function(){
         alert(rose.name+" is saying hello to everyone.");
           }; 
      return rose;   
}  
 

  对象在通过上述三个阶段创建后,对象上的任何访问和操作都只与对象自身及其原型链上的那串对象有关,与构造函数再扯不上关系了。换句话说,构造函数只是在创建对象时起到介绍原型对象和初始化对象两个作用。

   我们再深入想想,如果我们要创建1000个rose这样子的对象,上述的三个阶段是不是要执行1000次呢?答案是。这样子就太消耗性能,那有什么方法解决呢。就是通过prototype来优化了,优化后的代码如下

------------------------------------------------------------------------

 

functon createPerson(name,sex,birthday) {   

             this.name = name ;
             this.sex = sex;
             this.birthday = birthday;
            return this;   
} 

createPerson.prototype.sayHi =  function(){
      alert(this.name+"  is saying hello to everyone.");
};
 

------------------------------------------------------------------------

     上述代码,在运行的过程中就赋予了createPerson对象具有sayHi属性,而不是在构造函数中再进行初始化设置,无疑是对性能的一个质的提升。
     然后通过

var rose = new createPerson('Rose','female','1985-01-01');
var lily = new createPerson('Lily ','female','1985-01-01');
rose.sayHi();
lily.sayHi();
//输出的结果是

Rose is saying hello to everyone.

Lily  is saying hello to everyone.

运行的结果正是我们想得到的结果。但这时可能你有疑问了,如果,函数对象和函数原型对象都同时具有sayHi方法,这时结果会怎么样子呢?还是先看如下代码

 

function createPerson(name,sex,birthday,canSay) {   
   this.name = name ;
   this.sex = sex;
   this.birthday = birthday;
   if(canSay) {
      this.sayHi = function(){
      alert(this.name+"is saying hello to everyone.");
      };   
    }
    return this;   
}   
createPerson.prototype.sayHi =  function(){
      alert(" Somebody is saying hello to everyone.");
};

var rose = new createPerson('Rose','female','1985-01-01',true);
var lily = new createPerson('哑吧','female','1985-01-01',false);
rose.sayHi();
lily.sayHi();

//运行的结果是

Rose is saying hello to everyone.

Somebody is saying hello to everyone.

怎么去理解运行结果呢?原来JS对象,在查找自身属性的时候,会先从对象的内置对象链查找是否存在该属性。因此不难理解 rose.sayHi() 的运行结果:Rose is saying hello to everyone.但是对于lily.sayHi();的运行结果又是怎么回事呢?原来JS对象先从对象的内置对象链查找是否存在该属性,查找到则返回, 如果查找不到,再去对象原型链查找,可见lily对象会从createPerson.prototype.sayHi =  function(){
      alert(" Somebody is saying hello to everyone.");
};原型链中查找返回然后再调用sayHi方法,因而得到的结果就是 Somebody is saying hello to everyone

 

 

=========================分割线==========================================

 

分享到:
评论

相关推荐

    深入理解javascript原型和闭包

    深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系

    js 原型对象和原型链理解

    而Object的原型对象用Object.__proto__ = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。原型对象的用途是为每个实例对象存储共享...

    JavaScript核心(对象、原型、继承、上下文、闭包、this).pdf

    面向对象概念(对象封装,各种继承,闭包原理,this作用域等)介绍清晰易懂

    深入理解JavaScript系列

    深入理解JavaScript系列(5):强大的原型和原型链 深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP 深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP 深入理解JavaScript系列(8):...

    JavaScript 面向对象编程详细讲解文档

    原型是理解继承概念的关键, 我们将会教你如何建立原型, 如何检测一个对象是否是另外一个对象的原型, 及其 JavaScript 的模型与Java 面向对象编程之间的区别。我们同样会向你展示如何检测对象所包含的各种属性的方法...

    JavaScript你一定要搞懂的原型链

    能学到什么:理解原型链对于 JavaScript 开发者来说非常重要,因为它影响了对象的属性访问、继承和代码复用等方面。通过掌握原型链的概念和工作原理,开发者可以更好地利用 JavaScript 的面向对象特性。 这是一个可...

    深入理解JavaScript系列(.chm)

    深入理解JavaScript系列(5):强大的原型和原型链 深入理解JavaScript系列(6):S O L I D五大原则之单一职责SRP 深入理解JavaScript系列(7):S O L I D五大原则之开闭原则OCP 深入理解JavaScript系列(8):...

    学习javascript面向对象 理解javascript原型和原型链

    主要介绍了javascript原型和原型链,学习javascript面向对象,感兴趣的小伙伴们可以参考一下

    深入理解javascript原型和闭包1

    在咱们的第一节(深入理解javascript原型和闭包(1)——一切都是对象)中说道,函数也是一种对象。他也是属性的集合,你也可以对函数进行自定义属性。不用等咱

    深入理解javascript原型链和继承

    在上一篇文章中,介绍了原型的概念,了解到在javascript中构造函数、原型对象、实例三个好基友之间的关系:每一个构造函数都有一个“守护神”——原型对象,原型对象心里面也存着一个构造函数的“位置”,两情相悦,...

    javascript 原型与原型链的理解及应用实例分析

    本文实例讲述了javascript 原型与原型链的理解及应用。分享给大家供大家参考,具体如下: javascript中一切皆对象,但是由于没有Class类的概念,所以就无法很好的表达对象与对象之间的关系了。 比如对象A与对象B之间...

    深入理解javascript构造函数和原型对象

    对象,是javascript中非常重要的一个梗,是否能透彻的理解它直接关系到你对整个javascript体系的基础理解,说白了,javascript就是一群对象在搅。。(哔!)。

    深入理解JavaScript

    对 JavaScript 的介绍都是说他是基于对象的编程语⾔,⽽从没有哪本书会说 JavaScript 是⼀门⾯向对象的编程语⾔。基于对象很好理解,毕竟在 JavaScript 中⼀切都是对象,我们随时可以使⽤点号操作符来调 某个对象的...

    全面理解面向对象的 JavaScript(来自ibm)

    当今 JavaScript 大行其道,各种应用...要掌握好 JavaScript,首先一点是必须摒弃一些其他高级语言如 Java、C# 等类式面向对象思维的干扰,全面地从函数式语言的角度理解 JavaScript 原型式面向对象的特点。把握好这一

    javascript构造函数以及原型对象的理解

    以下是一个构造函数的例子 如果是实例方法,不同的实例化,它们引用的地址是不一样的,是唯一的。 //定义一个构造函数 function People(name,age){ this.name=name; this.age=age; this.dothings=function(){ ...

    player-prototypes:JavaScript原型简介

    初学者学习javascript或具有另一种面向对象语言的经验的开发人员,学习javascript并习惯于使用“类”来实现继承希望将一些javascript添加到他们的脚本库中的初学者前端设计师先决条件对javascript对象的理解基本...

    图文详解JavaScript的原型对象及原型链

    JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,其实市面上已经有非常多的文章在尝试说清楚,有一张所谓很经典的图,上面画了各种线条,一会连接...

    Javascript面向对象程序设计培训讲义

    由于JS不是纯的面向对象的语言,所以对象的继承是以原型函数的形式继承的,很多人刚开始接触的时候不太理解,但是JS这种以原型函数的形式实现面向对象技术,不仅是可行的,而且还为面向对象技术提供了动态继承的功能...

Global site tag (gtag.js) - Google Analytics