Item 18: Understand the Difference between Function, Method, and Constructor Calls

If  you’re  familiar  with  object-oriented  programming,  you’re  likely accustomed to thinking of functions, methods, and class constructors as three separate things. In JavaScript, these are just three different usage patterns of one single construct: functions.

The simplest usage pattern is the function call:

function  hello(username)  { 

return  "hello,  "  +  username;

}

hello("Keyser Söze");  //  "hello, Keyser Söze" 

This does exactly what it looks like: It calls the hello function and binds the name parameter to its given argument.

Methods in JavaScript are nothing more than object properties that happen to be functions:

var  obj  =  { 

hello:  function()  { 

return  "hello,  "  +  this.username;

},

username:  "Hans  Gruber"

};

obj.hello();  //  "hello,  Hans  Gruber" 

Notice how hello refers to this to access the properties of obj. You might be tempted to assume that this gets bound to obj because the hello method was defined on obj. But we can copy a reference to the same function in another object and get a different answer:

var  obj2  =  { 

hello:  obj.hello, 

username:  "Boo  Radley"
}; 

obj2.hello();  //  "hello,  Boo  Radley" 

What really happens in a method call is that the call expression itself 
determines  the  binding  of  this,  also  known  as  the  call’s  receiver. 
The  expression  obj.hello()  looks  up  the  hello  property  of  obj  and 
calls  it  with  receiver  obj.  The  expression  obj2.hello()  looks  up  the 
hello  property  of  obj2—which  happens  to  be  the  same  function  as 
obj.hello—but calls it with receiver obj2. In general, calling a method 
on an object looks up the method and then uses the object as the 
method’s receiver.

Since methods are nothing more than functions called on a particu-
lar object, there is no reason why an ordinary function can’t refer to 
this:

function  hello()  { 

return  "hello,  "  +  this.username;

}

This can be useful for predefining a function for sharing among multiple objects: 

var  obj1  =  { 

hello:  hello, 

username:  "Gordon  Gekko"

};

obj1.hello();  //  "hello,  Gordon  Gekko"

var  obj2  =  {

hello:  hello,

username:  "Biff  Tannen"

};

obj2.hello();  //  "hello,  Biff  Tannen" 

However, a function that uses this is not particularly useful to call as a function rather than a method:

hello();  //  "hello,  undefined" 

Rather  unhelpfully,  a  nonmethod  function  call  provides  the  global object as the receiver, which in this case has no property called name and produces undefined. Calling a method as a function rarely does anything useful if the method depends on this, since there is no reason  to  expect  the  global  object  to  match  the  expectations  that  the method has of the object it is called on. In fact, binding to the global object is a problematic enough default that ES5’s strict mode changes the default binding of this to undefined:

function  hello()  {

"use  strict";

return  "hello,  "  +  this.username;

}

hello();  //  error:  cannot  read  property  "username"  of  undefined

This  helps  catch  accidental  misuse  of  methods  as  plain  functions by  failing  more  quickly,  since  attempting  to  access  properties  of undefined immediately throws an error.

The third use of functions is as constructors. Just like methods and plain functions, constructors are defined with function:

function  User(name,  passwordHash)  { 

this.name  =  name; 

this.passwordHash  =  passwordHash;

}

Invoking User with the new operator treats it as a constructor: 

var  u  =  new  User("sfalken", 

"0ef33ae791068ec64b502d6cb0191387"); 

u.name;  //  "sfalken" 

Unlike function calls and method calls, a constructor call passes a brand-new object as the value of this, and implicitly returns the new object as its result. The constructor function’s primary role is to initialize the object.

Things to Remember

? Method  calls  provide  the  object  in  which  the  method  property  is looked up as their receiver.

? Function calls provide the global object (or undefined for strict functions) as their receiver. Calling methods with function call syntax is rarely useful.

? Constructors are called with new and receive a fresh object as their receiver.

时间: 2024-10-19 07:16:47

Item 18: Understand the Difference between Function, Method, and Constructor Calls的相关文章

Item 18:让接口容易被正确使用,不易被误用 Effective C++笔记

Item 18: Make interfaces easy to use correctly and hard to use incorrectly. "让接口容易被正确使用,不易被误用",这也是面向对象设计中的重要概念,好的接口在工程实践中尤其重要. 在使用优秀的第三方组件时,常常能够切身感受到好的接口原来可以这么方便,甚至不需记住它的名字和参数就能正确地调用. 反观自己写的API,常常会有人三番五次地问这个参数怎么设置,真是失败.人非圣贤孰能无过,只能在这种痛苦的驱动下努力的重构和

javascript工厂函数(factory function)vs构造函数(constructor function)

如果你从其他语言转到javascript语言的开发,你会发现有很多让你晕掉的术语,其中工厂函数(factory function)和构造函数(constructor function)就是其中的一个.本文试图理顺这两者之间的区别. Factory functions 工厂函数是将返回一个新的object的任何不是类或者构造函数的函数.在js中,任何函数都能够返回一个object.如果我们不是通过new function()的方式来获得这个对象的,那么她就是一个factory工厂函数. funct

Effective JavaScript Item 18 理解Function, Method, Constructor调用之间的区别

本系列作为Effective JavaScript的读书笔记. Function绝对是JavaScript中的重中之重.在JavaScript中,Function承担了procedures, methods, constructors甚至是classes以及modules的功能. 在面向对象程序设计中,functions,methods以及class constructor往往是三件不同的事情,由不同的语法来实现.但是在JavaScript中,这三个概念都由function来实现,通过三种不同的

What is the difference between routine , method , procedure , function ? please explain it with example?

a method is named and attached to an object. so, for example, a method is like a function but is contained inside a class. its scope is limited to that class, and cannot affect variables outside that class, even global variables. if you need to affec

[Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断

条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 template<typename T> void f(ParamType param); // 函数模板形式 f(expr); // 函数调用 存在T的类型即为expr类型的情况,如下T为int templat<typename T> void f(const T& param

[Effective Modern C++] Item 3. Understand decltype - 了解decltype

了解decltype 基础知识 提供一个变量或者表达式,decltype会返回其类型,但是返回的内容会使人感到奇怪. 以下是一些简单的推断类型: const int i = 0; // decltype(i) -> const int bool f(const Widget& w); // decltype(w) -> const Widget&, decltype(f) -> bool(const Widget&) struct Point { int x, y

Effective Java 英文 第二版 读书笔记 Item 3:Enforce the singleton property with a private constructor or an enum type.

Making a class a singleton can make it difficult to test clients. package singletonProperty; //ingleton with public final field public class ElvisField { public static final ElvisField INSTANCE=new ElvisField(); private ElvisField(){ } } package sing

Effective Java 英文 第二版 读书笔记 Item 2:Consider a builder when faced with many constructor parameters.

package builderManyPara; //JavaBeans Pattern - allows inconsistency,mandates mutability public class NutritionFactsBean { // Parameters initialized to default values(if any) // required private int servingSize = -1; private int servings = -1; // opti

一份来自于全球的前端面试题清单,看看老外喜欢考哪些题(部分有答案)

方括号中的蓝色标题是题目的出处,有些题目在原址内包含答案.搜集的大部分外国前端面试题没有做翻译,单词并不难,大家应该看得懂.题目旁边的方括号内, 简单记录了与此题相关的知识点.总共大概一千多道,包含国内的题目,如有错误,欢迎指正.有些原链可能已无法打开,有些可能需要代理才能查看. 一.HTML [HTML related interview questions] 1.What is doctype? Why do u need it? 2.What is the use of data-* at