[Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同
面向对象编程中,函数、方法、类的构造函数是三种不同的概念。
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变量的对象。
按照上面的文字,画了一张图: 
由于方法其实就是通过特定对象调用的函数,不知为何一个普通的函数不能引用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"
上面这段代码的结构图应该是这样的。

如果直接调用
hello();//"hello,undefined"
一个非方法(nonmethod)的函数调用会将全局对象作为接收者,这时全局对象没有名为username的属性所以产生了undefined。
如果方法中需要使用this变量,则将方法作为函数调用则毫无用处,因为没有理由希望全局对象匹配调用对象中的方法。事实上,将this变量绑定到全局对象是有问题的,ES5严格模式将this变量的默认绑定值改为undefined
function hello(){
'use strict';
return 'hello,'+this.username;
}
hello();
结果如图

这样做可以有助于更快地捕获偶然地将方法错误地作为纯函数使用的情况。
通过构造函数使用
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运算符调用,并产生一个新的对象作为其接收者
[Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同的更多相关文章
- [Effective JavaScript 笔记]第50条:迭代方法优于循环
"懒"程序员才是好程序员.复制和粘贴样板代码,一但代码有错误,或代码功能修改,那么程序在修改的时候,程序员需要找到所有相同功能的代码一处处进行修改.这会使人重复发明轮子,而且在别人 ...
- [Effective JavaScript 笔记] 第13条:使用立即调用的函数表达式创建局部作用域
function wrapElements(a){ var res=[],i,n; for(i=0,n=a.length;i<n;i++){ res[i]=function(){return a ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第20条:使用call方法自定义接收者来调用方法
不好的实践 函数或方法的接收者(即绑定到特殊关键字this的值)是由调用者的语法决定的.方法调用语法将方法被查找的对象绑定到this变量,(可参阅之前文章<理解函数调用.方法调用及构造函数调用之 ...
- [Effective JavaScript 笔记]第55条:接收关键字参数的选项对象
53节建议保持参数顺序的一致约定对于帮助程序员记住每个参数在函数调用中的意义很重要.参数较少这个主意不错,但如果参数过多后,就出现麻烦了,记忆和理解起来都不太容易. 参数蔓延 如下面这些代码: var ...
- [Effective JavaScript 笔记]第33条:使构造函数与new操作符无关
当使用函数作为一个构造函数时,程序依赖于调用者是否记得使用new操作符来调用该构造函数.注意:该函数假设接收者是一个全新的对象. 一个例子 function User(name,pwd){ this. ...
随机推荐
- 【总结】学习Socket编写的聊天室小程序
1.前言 在学习Socket之前,先来学习点网络相关的知识吧,自己学习过程中的一些总结,Socket是一门很高深的学问,本文只是Socket一些最基础的东西,大神请自觉绕路. 传输协议 TCP:Tra ...
- flatbuffers 使用问题记录
1. 命名空间的问题 ----------------------------- namespace 1.0.3 版本包含文件类型前面不需要加命名空间,但是1.1.0 中包含需要在类型前加命名空间 i ...
- jquery扩展函数详解(我的人生颠覆)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上次分析了jquery的源码 ...
- [USACO2004][poj1989]The Cow Lineup(乱搞)
http://poj.org/problem?id=1989 题意:求一个序列的最短非子序列长度l,即长度小于l的所有数的排列都是原序列的子序列(不一定要连续的),求l得最小值. 分析: 我们从左到右 ...
- 04.C#类型系统、值类型和引用类型(二章2.2-2.3)
今天要写的东西都是书中一些概念性的东西,就当抄笔记,以提问对话的方式将其写出来吧,说不定以后面试能有点谈资~~~ Q1.C#1系统类型包含哪三点特性? A1.C#1类型系统是静态的.显式的和安全的. ...
- jQuery使用之(四)处理页面的表单元素
表单是一个特殊的页面元素,value的值是最受关注的,jQuery提供了强大的val()方法来处理相关的操作. 1.获取表单元素的值. 直接调用val()方法时可以获取选择器的 中的第一个元素的val ...
- MVC——应用Ajax获取不到数据问题解答
当我们使用控制器利用Ajax获取表单数据时,调试为null,这时看看你接受表单时定义的参数名字是否为action 其实不能起这个名字的,这个名字和控制器关键字冲突了 随便换个其它名字就好了,比如我起个 ...
- u1-nav-html
<header id="masthead" class="masthead" role="banner"> <nav cl ...
- 【HDU 1445】Ride to School
题 题意 骑自行车,等0时开始最早出发的人,一起出发,然后被别人超过时,就追上去,终点距离是4.5km,速度单位是km/s,求到达的时间(s). 分析 贪心,找0时开始最早到的即可. 代码 #incl ...
- 【HDU 5387】Clock
题 Description Give a time.(hh:mm:ss),you should answer the angle between any two of the minute.hour. ...