[Effective JavaScript 筆記]第18條:理解函數調用、方法調用及構造函數調用之間的不同

来源:http://www.cnblogs.com/wengxuesong/archive/2016/05/25/5526533.html
-Advertisement-
Play Games

面向對象編程中,函數、方法、類的構造函數是三種不同的概念。 JS中,它們只是單個構造對象的三種不同的使用模式。 三種不同的使用模式 函數調用 函數的表現與行為一致,調用hello函數並將給定的實參綁定到username形參。 方法調用 js中的方法,是指對象的屬性恰好是函數而已。 這裡方法hello ...


面向對象編程中,函數、方法、類的構造函數是三種不同的概念。
JS中,它們只是單個構造對象的三種不同的使用模式。

三種不同的使用模式

函數調用

function hello(username){
	return 'hello,'+username;
} 
hello('world');//"hello,world"

函數的表現與行為一致,調用hello函數並將給定的實參綁定到username形參。

方法調用

js中的方法,是指對象的屬性恰好是函數而已。

var obj={
   hello:function(){
	return 'hello,'+this.username;
   },
   username:'world'
};
obj.hello();//"hello,world"

這裡方法hello是通過this變數來訪問obj對象的屬性的。 

this的指向是如何完成的呢?從上面的這個例子中,可能傾向於this變數被綁定到obj對象了,由於hello方法定義在obj對象中。
下麵看一個例子  

var obj2={
    hello:obj.hello,
    username:'han mei mei.'
}
obj2.hello();//"hello,han mei mei."

事實是,在方法調用的時候才由表達式來確定this變數的綁定情況。 

綁定到this變數的對象被稱為調用接收者(receiver)。
表達式obj.hello()在obj對象中查找名為hello的屬性,並將obj對象作為接收者,然後調用該屬性。
表達式obj2.hello()在obj2對象中查找名為hello的屬性,恰巧是obj.hello函數,但是接收者是obj2對象。
通常,通過某個對象調用方法將查找該方法並將對象作為該方法的接收者,也即this變數的對象。
按照上面的文字,畫了一張圖:
1464147280602
由於方法其實就是通過特定對象調用的函數,不知為何一個普通的函數不能引用this變數。

function hello(){
    return 'hello,'+this.username;
}

var obj1={
    hello:hello,
    username:'obj1'
}
var obj2={
    hello:hello,
    username:'obj2'
}
obj1.hello();//"hello,obj1"
obj2.hello();//"hello,obj2"

上面這段代碼的結構圖應該是這樣的。 

1464148054539

如果直接調用 

hello();//"hello,undefined"

一個非方法(nonmethod)的函數調用會將全局對象作為接收者,這時全局對象沒有名為username的屬性所以產生了undefined。 

如果方法中需要使用this變數,則將方法作為函數調用則毫無用處,因為沒有理由希望全局對象匹配調用對象中的方法。事實上,將this變數綁定到全局對象是有問題的,ES5嚴格模式將this變數的預設綁定值改為undefined

function hello(){
    'use strict';
    return 'hello,'+this.username;
}
hello();

結果如圖 

1464148382256
這樣做可以有助於更快地捕獲偶然地將方法錯誤地作為純函數使用的情況。

通過構造函數使用

就像方法和純函數一樣,構造函數也是由function運算符定義的。
function User(name,pwd){
     this.name=name;
     this.pwd=pwd;
}
var u=new User('li lei','asdfxov2-3409');
u.name;//"li lei"

與函數調用和方法調用不同的是,構造函數調用將一個全新的對象作為this變數的值,並隱式返回這個新對象作為調用結果。構造函數的主要職責是初始化該新對象。

提示

  • 方法調用將被查找方法屬性的對象作為調用接收者(this綁定)

  • 函數調用將全局對象(處於嚴格模式下則為undefined)作為其接收者。很少使用函數調用語法來調用方法。

  • 構造函數需要通過new運算符調用,並產生一個新的對象作為其接收者


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、String類String類在java.lang包中,java使用String類創建一個字元串變數,字元串變數屬於對象。java把String類聲明的final類,不能有類。String類對象創建後不能修改,由0或多個字元組成,包含在一對雙引號之間。二、String類對象的創建字元串聲明:Str ...
  • 單例模式最初的定義出現於《設計模式》(艾迪生維斯理, 1994):“保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。” 特點:一是某個類只能有一個實例; 二是它必須自行創建這個實例; 三是它必須自行向整個系統提供這個實例。 一、經典實現 二、靜態構造函數實現 三、靜態變數實現 測試: ...
  • 市長信箱郵件查詢服務: 使用Elasticsearch 替代 Mysql 我在上一篇文章中實現了一個基於Springboot構建的web應用: 市長信箱郵件查詢服務. 應用將郵件信息抓取後保存在Mysql中,用以提供給搜索Web使用.Mysql雖然集成簡單,能快速實現功能, 但like查詢性能一般, ...
  • 學習要點: 1.大綱演算法 2.section和div 3.結構分析 主講教師:李炎恢 本章主要開始使用學慣用HTML5和CSS3來構建Web頁面,第一個項目採用PC端 固定佈局來實現。 一.大綱演算法 在HTML5中有一個很重要的概念,叫做HTML5大綱演算法(HTML5Outliner),它的用途是為 ...
  • 1、Table(Grid)參考地址 "https://github.com/samu/angular table" "https://github.com/daniel nagy/md data table" "https://github.com/davidjnelson/angular tabl ...
  • 引言 本文摘自《JavaScript設計模式與開發實踐》 在現實中,很多時候也有多種途徑到達同一個目的地。比如我們要去某個地方旅游,可以根據具體的實際情況來選擇出行的線路。 如果沒有時間但是不在乎錢,可以選擇坐飛機。 如果沒有錢,可以選擇坐大巴或者火車。 如果再窮一點,可以選擇騎自行車。 在程式設計 ...
  • 最近在研讀 《CSS SECRET》(CSS揭秘)這本大作,對 CSS 有了更深層次的理解,折騰了下麵這個項目: CSS3奇思妙想 -- Demo (請用 Chrome 瀏覽器打開,非常值得一看)。採用單標簽完成各種圖案,許多圖案與本文有關。 也希望覺得不錯的同學順手在我的 Github 點個 st ...
  • 一、原生js: 二、jquery版本: 採用deferred對象返回結果 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...