zoukankan      html  css  js  c++  java
  • javascript中的this与prototype,原型理解

    JavaScript 函数调用

    JavaScript 函数有 4 种调用方式。

    每种方式的不同方式在于 this 的初始化。

    this 关键字

    一般而言,在Javascript中,this指向函数执行时的当前对象

     

    注意 this 是保留关键字,你不能修改 this 的值。

    全局对象

    当函数没有被自身的对象调用时, this 的值就会变成全局对象。

    在 web 浏览器中全局对象是浏览器窗口(window 对象)。

    该实例返回 this 的值是 window 对象:

    1作为一个函数调用

    实例

    function myFunction(a, b) {
        return a * b;
    }
    myFunction(10, 2);           // myFunction(10, 2) 返回 20

    2函数作为方法调用

    实例

    var myObject = {
        firstName:"John",
        lastName: "Doe",
        fullName: function () {
            return this.firstName + " " + this.lastName;
        }
    }
    myObject.fullName();         // 返回 "John Doe"

    注意

    函数作为对象方法调用,会使得 this 的值成为对象本身。

    3使用构造函数调用函数

    如果函数调用前使用了 new 关键字, 则是调用了构造函数。

    实例

    // 构造函数:
    function myFunction(arg1, arg2) {
        this.firstName = arg1;
        this.lastName  = arg2;
    }

    // This creates a new object
    var x = new myFunction("John","Doe");
    x.firstName;                             // 返回 "John"

    构造函数的调用会创建一个新的对象。新对象会继承构造函数的属性和方法。

     

    构造函数中 this 关键字没有任何的值。
    this 的值在函数调用时实例化对象(new object)时创建。

    4作为函数方法调用函数

    在 JavaScript 中, 函数是对象。JavaScript 函数有它的属性和方法。

    call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。

    实例

    Function  myObject(){}

    function myFunction(a, b) {
        return a * b;
    }
    myFunction.call(myObject, 10, 2);//返回20

    function myFunction(a, b) { return a * b; }

    myArray = [10,3];

     myFunction.apply(myObject, myArray);//返回30

    两个方法都使用了对象本身作为第一个参数。 两者的区别在于第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。

    闭包深入:http://www.cnblogs.com/onepixel/p/5062456.html

    1 原型法设计模式

    在.Net中可以使用clone()来实现原型法

    原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。

    2 javascript的方法可以分为三类:

    a 类方法

    b 对象方法

    c 原型方法

    例子:

    function People(name)
    {
      this.name=name;
      //对象方法
      this.Introduce=function(){
        alert("My name is "+this.name);
      }
    }
    //类方法
    People.Run=function(){
      alert("I can run");
    }
    //原型方法
    People.prototype.IntroduceChinese=function(){
      alert("我的名字是"+this.name);
    }
    
     
    
    //测试
    
    var p1=new People("Windking");
    
    p1.Introduce();
    
    People.Run();
    
    p1.IntroduceChinese(); 
    

      

    prototype是什么含义?

    javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。

    A.prototype = new B();

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

    先看一个实验的例子:

    function baseClass()
    {
      this.showMsg = function()
      {
         alert("baseClass::showMsg");   
      }
    }
    
    function extendClass()
    {
    }
    
    extendClass.prototype = new baseClass();
    var instance = new extendClass();
    instance.showMsg(); // 显示baseClass::showMsg
    

      

    我们首先定义了baseClass类,然后我们要定义extentClass,但是我们打算以baseClass的一个实例为原型,来克隆的extendClass也同时包含showMsg这个对象方法。

    extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。

    那么就会有一个问题,如果extendClass中本身包含有一个与baseClass的方法同名的方法会怎么样?

    下面是扩展实验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不会克隆同名函数。

    那么又会有一个新的问题:

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

    3 obj1.func.call(obj)方法

    意思是将obj看成obj1,调用func方法

    答案是可以使用call:

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

      

    这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”

    好了,这里可能有人会问,为什么不用baseClass.showMsg.call(instance);

    这就是对象方法和类方法的区别,我们想调用的是baseClass的对象方法

    最后,下面这个代码如果理解清晰,那么这篇文章说的就已经理解了:

    <script type="text/javascript">
    
    function baseClass()
    {
        this.showMsg = function()
        {
            alert("baseClass::showMsg");   
        }
       
        this.baseShowMsg = function()
        {
            alert("baseClass::baseShowMsg");
        }
    }
    baseClass.showMsg = function()
    {
        alert("baseClass::showMsg static");
    }
    
    function extendClass()
    {
        this.showMsg =function ()
        {
            alert("extendClass::showMsg");
        }
    }
    extendClass.showMsg = function()
    {
        alert("extendClass::showMsg static")
    }
    
    extendClass.prototype = new baseClass();
    var instance = new extendClass();
    
    instance.showMsg(); //显示extendClass::showMsg
    instance.baseShowMsg(); //显示baseClass::baseShowMsg
    instance.showMsg(); //显示extendClass::showMsg
    
    baseClass.showMsg.call(instance);//显示baseClass::showMsg static
    
    var baseinstance = new baseClass();
    baseinstance.showMsg.call(instance);//显示baseClass::showMsg
    
    </script>
    

      

    转载于 http://www.cnblogs.com/yjf512/archive/2011/06/03/2071914.html 

  • 相关阅读:
    OK335x mksd.sh hacking
    Qt jsoncpp 对象拷贝、删除、函数调用 demo
    OK335xS 256M 512M nand flash make ubifs hacking
    Qt QScrollArea and layout in code
    JsonCpp Documentation
    Qt 4.8.5 jsoncpp lib
    Oracle数据库生成UUID
    freemarker得到数组的长度
    FreeMarker中if标签内的判断条件
    freemarker语法
  • 原文地址:https://www.cnblogs.com/xiaohuasan/p/5219945.html
Copyright © 2011-2022 走看看