鍍金池/ 問答/Java  網(wǎng)絡(luò)安全  HTML/ javascript高級程序設(shè)計(jì) 安全作用域構(gòu)造函數(shù) 問題

javascript高級程序設(shè)計(jì) 安全作用域構(gòu)造函數(shù) 問題

書上的解釋不太理解,求大神幫解釋下。
為什么第一種沒有繼承到sides屬性

clipboard.png

// 創(chuàng)建作用域安全的構(gòu)造函數(shù)
function Polygon(sides) {
    if (this instanceof Polygon) {
        console.log('this', this);
        this.sides = sides;
        this.getArea = function(){
            return 0;
        }
    } else {
        return new Polygon(sides);
    }
}

// 非作用域安全的構(gòu)造函數(shù)
function Rectangle(width, height) {
    Polygon.call(this, 2);  
    this.width = width;
    this.height = height;
    this.getArea = function (){
        return this.width * this.height;
    }
}

let rect = new Rectangle(5,10);
console.log(rect.sides);

為什么rect沒有繼承到side屬性

而通過原型就可以

Rectangle.prototype = new Polygon();
let rect = new Rectangle(2,4);
console.log(rect.sides);// 2
回答
編輯回答
選擇

if (this instanceof Polygon)
這句不是判斷了么?

如果當(dāng)前的this是由Plolygon構(gòu)造的就把當(dāng)前this.sides = sides,否則返回實(shí)例化過的Plolygon。

樓主的問題真是漏洞百出啊。首先js繼承沒搞清楚,其次instanceof不懂,再次,call具體作用沒搞清楚····

2017年6月7日 12:11
編輯回答
吃藕丑

JavaScript 的繼承是通過原型鏈實(shí)現(xiàn)。
沒有下面的語句:

Rectangle.prototype = new Ploygon();

無法實(shí)現(xiàn) Rectangle 繼承 Polygon。

在 Rectangle 函數(shù)中,Polygon.call(this,2) 只是相當(dāng)于調(diào)用了基類的構(gòu)造函數(shù)。但是前提是,你要先實(shí)現(xiàn)繼承,沒有繼承關(guān)系,這個(gè)調(diào)用沒啥效果。

2018年4月10日 01:14
編輯回答
入她眼

Polygon.call(this, 2);的時(shí)候 Polygon 中的this指向 Rectangle 而不是 Polygon
而當(dāng)你 new Polygon的時(shí)候,this指向就是 Polygon了

主要還是call的用法的關(guān)系

2017年7月15日 12:17
編輯回答
毀與悔

寫在注釋里了

    // 創(chuàng)建作用域安全的構(gòu)造函數(shù)
    function Polygon(sides) {
        if (this instanceof Polygon) {
            debugger;  // (3) 此時(shí) this 是 Polygon 實(shí)例,所以執(zhí)行到了這里
            console.log('this', this);  
            this.sides = sides;
            this.getArea = function(){
                return 0;
            }
        } else {
            debugger;  // (1) 調(diào)用 Polygon.call(this, 2) 時(shí) this 不是 Polygon 的實(shí)例 所以先執(zhí)行到了這里
            return new Polygon(sides);  // (2) 此時(shí)返回了一個(gè) Polygon實(shí)例
        }
    }

    // 非作用域安全的構(gòu)造函數(shù)
    function Rectangle(width, height) {
        // 執(zhí)行(2)返回了一個(gè)Polygon實(shí)例 但是你沒有用到 也就是沒有賦給變量 所以在 new Rectangle(5,10) 時(shí)候不會繼承sides
        Polygon.call(this, 2); 
        this.width = width;
        this.height = height;
        this.getArea = function (){
            return this.width * this.height;
        }
    }

    let rect = new Rectangle(5,10);
    console.log(rect);

    // Rectangle 的原型鏈直接指向了一個(gè) Polygon 實(shí)例, 那么new Rectangle(5,10)時(shí)候, 所有的Rectangle實(shí)例都會繼承sides,因?yàn)椴檎覍ο髮傩詴r(shí)如果在當(dāng)前對象上找不到,就會順著原型鏈一直找
    Rectangle.prototype = new Polygon(); 

    // 比如這個(gè)例子
    let obj = { a:1 };
    obj.__proto__.b = 2; // 屬性b在obj的原型鏈上
    console.log(obj);  // { a: 1 }
    console.log(obj.b); // 2
2017年8月23日 13:00
編輯回答
吃藕丑

第一種情況,當(dāng)你let rect = new Rectangle(5,10);時(shí),此時(shí)rect是Rectangle的一個(gè)實(shí)例,Polygon.call(this, 2); 中this指代rect,你把rect作為Polygon的this來調(diào)用Polygon,當(dāng)在Polygon中判斷(this instanceof Polygon)這句話時(shí),發(fā)現(xiàn)this也就是rect不是Polygon的實(shí)例,根據(jù)instanceof的用法它會查找this的原型鏈,原型鏈中是否有Polygon的實(shí)例,如果找到就返回true。顯然沒找到,所以實(shí)際上Polygon.call(this, 2);這句話相當(dāng)于執(zhí)行了new Polygon(2),與rect無關(guān),所以rect中沒有sides屬性。
第二中情況:Rectangle.prototype = new Polygon();你讓Rectangle.prototype變?yōu)镻olygon的一個(gè)實(shí)例(這其實(shí)是javascript的原型繼承),看個(gè)例子:

function FOO(){} 
function Foo(){} 
Foo.prototype = new FOO();
 
var foo = new Foo();          //
foo.__proto__===Foo.prototype;
console.log(foo instanceof Foo)//true 
console.log(foo instanceof FOO)//true,根據(jù)foo的原型鏈找到了FOO的實(shí)例

因此第二種情況中Polygon.call(this, 2);它執(zhí)行的是if語句中的代碼,把sides和getArea放到了this中,所以rect.sides會是2。

2017年4月22日 10:50