JavaScript——實現對象繼承的五種方式(對象冒充 call apply 原型璉)

  • 首先明確this在javascript當中的指的是調用者,在java中指的是當前對象,這兩者有本質區別的
  • JavaScript中沒有類的概念,繼承描述對象之間的關系,繼承關鍵在于子類獲取父類的成員及方法的方式

1. 對象冒充

        function Parent(name)
        {
            this.name = name;
            this.sayHello = function()
            {
                alert(this.name)
            }
        }

        function Child(name, age)
        {
            //3行關鍵代碼 此三行用于獲取父類的成員及方法
            //用子類的this去冒充父類的this,實現繼承
            //父類Parent中的this.name、sayHello,分別成為了子類的成員、子類的方法
            this.method = Parent;
            //接收子類的參數 傳給父類
            this.method(name);
            //刪除父類
            delete this.method;
            
            //此后的this均指子類
            this.age = age;
            this.sayWorld = function()
            {
                alert(age);
            }
        }
        var parent = new Parent("張三");
        var child = new Child("李四", 20);

        parent.sayHello();
        child.sayHello();
        child.sayWorld();

2. call 方法方式

//call 方法是 Function 對象中的方法,因此我們定義的每個函數都擁有該方法。
//可以通過函數名來調用call 方法,call 方法的第一個參數會 被傳遞給函數中的this,
//從第 2 個參數開始,逐一賦值給函數中的參數

//call方法的使用
function test(str, str2)
{
    alert(this.name + ", " + str + ", " + str2);
}

var object = new Object();
object.name = "zhangsan";

//test.call相當于調用了test函數
//將object賦給了this
test.call(object, "JavaScript", "hello"); 

//call方法實現繼承
 function Parent(name)
    {
        this.name = name;
        this.sayHello = function()
        {
            alert(name);
        }
    }

    function Child(name, age)
    {
//子類的this傳給父類
        Parent.call(this, name);
        this.age = age;
        this.sayWorld = function()
        {
            alert(age);
        }
    }

    var parent = new Parent("張三");
    var child = new Child("李四", 20);

    parent.sayHello();
    child.sayHello();
    child.sayWorld();

3. apply方法方式

//call 和 apply 都是為了改變某個函數運行時的 context (上下文)而存在的,
//是為了改變函數體內部 this 的指向,劫持其他對象的方法
//call 和 apply二者的作用完全一樣,只是接受參數的方式不太一樣,apply第二個參數是一個參數列表
        function Parent(name)
        {
            this.name = name;
            this.sayHello = function()
            {
                alert(name);
            }
        }

        function Child(name, age)
        {
            Parent.apply(this, new Array(name));

            this.age = age;

            this.sayWorld = function()
            {
                alert(age);
            }
        }

        var parent = new Parent("張三");
        var child = new Child("李四", 30);

        parent.sayHello();
        child.sayHello();
        child.sayWorld();

4. 原型鏈方式(prototype chain )

//無法給構造函數傳參數
    function Parent()
    {

    }

    Parent.prototype.name = "張三";
    Parent.prototype.sayHello = function()
    {
        alert(this.name);
    }

    function Child()
    {

    }
    //子類的原型引用指向父類
    Child.prototype = new Parent();
    Child.prototype.age = 20;

    Child.prototype.sayWorld = function()
    {
        alert(this.age);
    }
        var child = new Child();
        child.sayHello();
        child.sayWorld();

5. 混合方式(克服了原型璉的弊端)

//將對象方法拿到對象的外面定義,封裝對象屬性
       function Parent(name)
       {
           this.name = name;
       }
        Parent.prototype.sayHello = function()
        {
            alert(this.name);
        }

        function Child(name, age)
        {//子類的this傳給parent
            Parent.call(this, name);
            this.age = age;
        }
        //子類的原型引用指向父類對象
        Child.prototype = new Parent();
        Child.prototype.sayWorld = function()
        {
            alert(this.age);
        }

        var child = new Child("李四", 30);
        child.sayHello();
        child.sayWorld();

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容