原生JS實現new方法、new一個對象發生的四部、new里面常用的優先級


一、js中new一個對象的過程

  首先了解new做了什么,使用new關鍵字調用函數(new ClassA(…))的具體步驟:

  1、創建一個新對象:

  var obj = {};

  2、設置新對象的constructor屬性為構造函數的名稱,設置新對象的__proto__屬性指向構造函數的prototype對象;

  obj.__proto__ = ClassA.prototype;

  3、使用新對象調用函數,函數中的this被指向新實例對象:

  ClassA.call(obj);  //{}.構造函數()

  4、將初始化完畢的新對象地址,保存到等號左邊的變量中

  注意:若構造函數中返回this或返回值是基本類型(number、string、boolean、null、undefined)的值,則返回新實例對象;若返回值是引用類型的值,則實際返回值為這個引用類型。

var foo = "bar"; function test () {   this.foo = "foo"; } new test();                 //test中的this指新對象,並未改變全局的foo屬性
console.log(this.foo);             // "bar"
console.log(new test().foo);  // "foo";

二、用原生JS實現new方法

// 通過分析原生的new方法可以看出,在new一個函數的時候, // 會返回一個func同時在這個func里面會返回一個對象Object, // 這個對象包含父類func的屬性以及隱藏的__proto__
function New(f) { //返回一個func
    return function () { var o = {"__proto__": f.prototype}; f.apply(o, arguments);//繼承父類的屬性
        return o; //返回一個Object
 } }

  首先寫一個父類方法(包含參數name,age):

function Person(name,age){ this.name = name; this.age = age; }
//new一個Person的實例p1做研究對比

var p1 = new Person("Richard", 22); //此時p1包含name、age屬性,同時p1的__proto__指向Person的prototype
p1.name;//Richard
p1.age;//22

  通過自定義New方法創建一個實例對象p2:

var p2 = New(Person)("Jack",25); p2.name;//Jack
p2.age;//25

  此時p2 instanceof Person 返回的是true;

Person.prototype.gender ="male"; p1.gender//male
p2.gender//male

三、優先級問題

  優先級由高到低:小括號(xxx)  >  屬性訪問.   >  new foo()  >  foo()

  注意new Foo()優先級高於Foo();

function getName(){ console.log(1) } function Foo() { this.getName = function () { console.log(2); }; return this; } Foo.getName = function () { console.log(3); }; //先從.屬性訪問符號開始往前面找一個最近的對象,同時注意new Foo()優先於Foo();
var a=new Foo.getName();//3;
屬性.的優先級高於new foo(),所以===new (Foo.getName)();返回Foo.getName類型的實例
var b=new Foo().getName();//2;
new foo()的優先級高於foo(),所以就相當於new foo()的屬性,===(new Foo()).getName();返回undefined
var c=new new Foo().getName();//2;
new foo()優先級低於屬性.,所以其實相當於就是new一個new foo()的getName屬性函數,===new (new Foo().getName)();返回Foo.getName類型的實例
new Date().getTime();//===((new Date()).getTime)() (new Date).getTime();//===((new Date()).getTime)() new Date.getTime();//Uncaught TypeError: Date(...).getTime is not a function;===new (Date.getTime)()

  需要注意的是:new Date 其實也是正確的,和new Date()一樣

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM