javascript高級知識分析——實例化

代碼信息來自於http://ejohn.org/apps/learn/。app

new作了什麼?

function Ninja(){ 
  this.name = "Ninja"; 
} 
 
var ninjaA = Ninja(); 
console.log( ninjaA, "undefined,ninja並非實例化" ); 
 
var ninjaB = new Ninja(); 
console.log( ninjaB.name == "Ninja", "true,在實例化裏存在name屬性" )

對一個函數進行new操做,這就是實例化。函數

上述代碼的流程爲,創造一個臨時對象,繼承Ninja.prototype對象,執行函數Ninja,一開始將上下文this設置爲臨時對象。沒有return語句,返回這個臨時對象。this

咱們的上下文this指向實例化對象

function Ninja(){ 
  this.swung = false; 
   
  // Should return true 
  this.swingSword = function(){ 
    this.swung = !this.swung; 
    return this.swung; 
  }; 
} 
 
var ninja = new Ninja(); 
console.log( ninja.swingSword(), "調用實例對象方法" ); 
console.log( ninja.swung, "引用實例對象屬性" ); 
 
var ninjaB = new Ninja(); 
console.log( !ninjaB.swung, "肯定this引用的屬性是實例化對象的屬性,實例化對象彼此不影響." );

習題:增長一個方法,能夠給ninja一個name屬性

function Ninja(name){ 
  //補足
} 
 
var ninja = new Ninja("John"); 
console.log( ninja.name == "John", "在初始化時name屬性就被設置" ); 
 
ninja.changeName("Bob"); 
console.log( ninja.name == "Bob", "name值成功修改" );

向實例化對象增長一個新的屬性和方法

function Ninja(name){ 
  this.changeName = function(name){
     this.name = name;
  }
  this.changeName(name)
} 
 
var ninja = new Ninja("John"); 
console.log( ninja.name == "John", "在初始化時name屬性就被設置" ); 
 
ninja.changeName("Bob"); 
console.log( ninja.name == "Bob", "name值成功修改" );

當沒有使用new時會發生什麼?

function User(first, last){ 
  this.name = first + " " + last; 
} 
 
var user = User("John", "Resig"); 
console.log( typeof user == "undefined", "由於沒有new,因此User做通常函數調用,沒有返回值" );
function User(first, last){ 
  this.name = first + " " + last; 
} 
 
window.name = "Resig"; 
var user = User("John", name); 
 
console.log( name == "John Resig", "全局屬性被覆蓋" );

當沒有new時,它其實就是通常的函數調用,遵循函數調用的本質。spa

確保在錯誤的狀況下仍然使用對象實例化

function User(first, last){ 
  if ( !(this instanceof User) ) 
    return new User(first, last); 
  this.name = first + " " + last; 
} 
 
var name = "Resig"; 
var user = User("John", name); 
 
console.log( user, "即便沒有使用new,仍然能夠正確實例化" ); 
console.log( name == "Resig", "實例化屬性正常" );

經過判斷this不是構造函數User的實例化對象,從新實例化,這是一個能夠不使用new進行實例化的技巧。prototype

習題:有沒有更加基因化的方法作一樣的事情?

function User(first, last){ 
  if ( !(this instanceof ___) ) 
    return new User(first, last); 
  this.name = first + " " + last; 
} 
 
var name = "Resig"; 
var user = User("John", name); 
 
console.log( user, "即便沒有使用new,仍然能夠正確實例化" ); 
console.log( name == "Resig", "實例化屬性正常" );

用arguments.callee實現

function User(first, last){ 
  if ( !(this instanceof ___) ) 
    return new User(first, last); 
  this.name = first + " " + last; 
} 
 
var name = "Resig"; 
var user = User("John", name); 
 
console.log( user, "即便沒有使用new,仍然能夠正確實例化" ); 
console.log( name == "Resig", "實例化屬性正常" );

arguments.callee引用的是函數自己。code

相關文章
相關標籤/搜索