JavaScript this调用规则说明


Posted in Javascript onMarch 08, 2010

JavaScript函数调用规则一
(1)全局函数调用:

function makeArray( arg1, arg2 ){ 
return [this , arg1 , arg2 ]; 
}

这是一个最常用的定义函数方式。相信学习JavaScript的人对它的调用并不陌生。
调用代码如下:
makeArray('one', 'two');
// => [ window, 'one', 'two' ]
这种方式可以说是全局的函数调用。
为什么说是全局的函数?
因为它是全局对象window 的一个方法,
我们可以用如下方法验证:
alert( typeof window.methodThatDoesntExist );
// => undefined
alert( typeof window.makeArray);
// => function
所以我们之前调用 makeArray的方法是和下面调用的方法一样的
window.makeArray('one', 'two');
// => [ window, 'one', 'two' ]
JavaScript函数调用规则二
(1)对象方法调用:
//creating the object 
var arrayMaker = { 
someProperty: 'some value here', 
make: makeArray 
}; 
arrayMaker.make('one', 'two'); // => [ arrayMaker, 'one', 'two' ] 
//或者用下面的方法调用: 
arrayMaker['make']('one', 'two'); // => [ arrayMaker, 'one', 'two' ]

看到这里跟刚才的区别了吧,this的值变成了对象本身.
你可能会质疑:为什么原始的函数定义并没有改变,而this却变化了呢?
非常好,有质疑是正确的。这里涉及到 函数在JavaScript中传递的方式,
函数在JavaScript 里是一个标准的数据类型,
确切的说是一个对象.你可以传递它们或者复制他们.
就好像整个函数连带参数列表和函数体都被复制,
且被分配给了 arrayMaker 里的属性 make,那就好像这样定义一个 arrayMaker :
var arrayMaker = { 
someProperty: 'some value here', 
make: function (arg1, arg2) { 
return [ this, arg1, arg2 ]; 
} 
};

如果不把调用规则二 弄明白,那么在事件处理代码中 经常会遇到各种各样的bug,举个例子:
<input type="button" value="Button 1" id="btn1" /> 
<input type="button" value="Button 2" id="btn2" /> 
<input type="button" value="Button 3" id="btn3" onclick="buttonClicked();"/> 
< script type="text/javascript"> 
function buttonClicked(){ 
var text = (this === window) ? 'window' : this.id; 
alert( text ); 
} 
var button1 = document.getElementById('btn1'); 
var button2 = document.getElementById('btn2'); 
button1.onclick = buttonClicked; 
button2.onclick = function(){ 
buttonClicked(); 
}; 
< /script>

点击第一个按钮将会显示”btn1”,因为它是一个方法调用,this为所属的对象(按钮元素) 。
点击第二个按钮将显示”window”,因为 buttonClicked 是被直接调用的( 不像 obj.buttonClicked() ),
这和第三个按钮,将事件处理函数直接放在标签里是一样的.所以点击第三个按钮的结果是和第二个一样的。
所以请大家注意:
button1.onclick = buttonClicked; 
button2.onclick = function(){ 
buttonClicked(); 
};

this指向是有区别的。
JavaScript函数调用规则三
当然,如果使用的是jQuery库,那么你不必考虑这么多,它会帮助重写this的值以保证它包含了当前事件源元素的引用。
//使用jQuery 
$('#btn1').click( function() { 
alert( this.id ); // jQuery ensures 'this' will be the button 
});

那么jQuery是如何重载this的值的呢?
答案是: call()和apply();
当函数使用的越来越多时,你会发现你需要的this 并不在相同的上下文里,这样导致通讯起来异常困难。
在Javascript中函数也是对象,函数对象包含一些预定义的方法,其中有两个便是apply()和call(),我们可以使用它们来对 this进行上下文重置。
<input type="button" value="Button 1" id="btn1" /> 
<input type="button" value="Button 2" id="btn2" /> 
<input type="button" value="Button 3" id="btn3" onclick="buttonClicked();"/> 
< script type="text/javascript"> 
function buttonClicked(){ 
var text = (this === window) ? 'window' : this.id; 
alert( text ); 
} 
var button1 = document.getElementById('btn1'); 
var button2 = document.getElementById('btn2'); 
button1.onclick = buttonClicked; 
button2.onclick = function(){ 
buttonClicked.call(this); // btn2 
}; 
< /script>

JavaScript函数调用规则四
(1)构造器
我不想深入研究在Javascript中类型的定义,但是在此刻我们需要知道在Javascript中没有类,
而且任何一个自定义的类型需要一个初始化函数,使用原型对象(作为初始化函数的一个属性)定义你的类型也是一个不错的想法,
让我们来创建一个简单的类型
//声明一个构造器 
function ArrayMaker(arg1, arg2) { 
this.someProperty = 'whatever'; 
this.theArray = [ this, arg1, arg2 ]; 
} 
// 声明实例化方法 
ArrayMaker.prototype = { 
someMethod: function () { 
alert( 'someMethod called'); 
}, 
getArray: function () { 
return this.theArray; 
} 
}; 
var am = new ArrayMaker( 'one', 'two' ); 
var other = new ArrayMaker( 'first', 'second' ); 
am.getArray(); 
// => [ am, 'one' , 'two' ] 
other.getArray(); 
// => [ other, 'first', 'second' ]

一个非常重要并值得注意的是出现在函数调用前面的new运算符,没有那个,你的函数就像全局函数一样,且我们创建的那些属性都将是创建在全局对象上(window),而你并不想那样。
另外一点,因为在你的构造器里没有返回值,所以如果你忘记使用new运算符,将导致你的一些变量被赋值为 undefined。
所以构造器函数以大写字母开头是一个好的习惯,这可以作为一个提醒,让你在调用的时候不要忘记前面的new运算符.
这样 初始化函数里的代码和你在其他语言里写的初始化函数是相似的.this的值将是你将创建的对象.
总结
我希望通过这些来使你们理解各种函数调用方式的不同,
让你的JavaScript代码远离bugs。
知道this的值是你避免bugs的第一步。
Javascript 相关文章推荐
解放web程序员的输入验证
Oct 06 Javascript
Js判断参数(String,Array,Object)是否为undefined或者值为空
Nov 04 Javascript
2014最热门的JavaScript代码高亮插件推荐
Nov 25 Javascript
基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解
Mar 05 Javascript
JS获得图片alt信息的方法
Apr 01 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
Aug 23 Javascript
js实现功能比较全面的全选和多选
Mar 02 Javascript
通过vue-cli来学习修改Webpack多环境配置和发布问题
Dec 22 Javascript
基于Node.js实现压缩和解压缩的方法
Feb 13 Javascript
微信小程序实现聊天室
Aug 21 Javascript
Openlayers实现点闪烁扩散效果
Sep 24 Javascript
javascript 放大镜 v1.0 基于Yui2 实现的放大镜效果
Mar 08 #Javascript
JavaScript中的闭包原理分析
Mar 08 #Javascript
ExtJS GridPanel 根据条件改变字体颜色
Mar 08 #Javascript
JavaScript 滚轮事件使用说明
Mar 07 #Javascript
javascript下4个跨浏览器必备的函数
Mar 07 #Javascript
Zero Clipboard js+swf实现的复制功能使用方法
Mar 07 #Javascript
GWT中复制到剪贴板 js+flash实现复制 兼容性比较好
Mar 07 #Javascript
You might like
PHP中usort在值相同时改变原始位置问题的解决方法
2011/11/27 PHP
Ajax请求PHP后台接口返回信息的实例代码
2018/08/21 PHP
Yii框架核心组件类实例详解
2019/08/06 PHP
HTML颜色选择器实现代码
2010/11/23 Javascript
js实现快速分享功能(你的文章分享工具)
2013/06/25 Javascript
纯js实现div内图片自适应大小(已测试,兼容火狐)
2014/06/16 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
2015/09/15 Javascript
JavaScript+html5 canvas实现图片破碎重组动画特效
2016/02/22 Javascript
jQuery遍历DOM节点操作之filter()方法详解
2016/04/14 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
2016/05/18 Javascript
vue引入js数字小键盘的实现代码
2018/05/14 Javascript
详解三种方式解决vue中v-html元素中标签样式
2018/11/22 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
JS多个异步请求 按顺序执行next实现解析
2019/09/16 Javascript
[57:53]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#3OG VS VP
2016/03/03 DOTA
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
使用Python的Twisted框架实现一个简单的服务器
2015/04/16 Python
Python弹出输入框并获取输入值的实例
2019/06/18 Python
python创建学生成绩管理系统
2019/11/22 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
快速解释如何使用pandas的inplace参数的使用
2020/07/23 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
Python 实现劳拉游戏的实例代码(四连环、重力四子棋)
2021/03/03 Python
发现两个有趣的CSS3动画效果
2013/08/14 HTML / CSS
HTML5 层的叠加的实现
2020/07/07 HTML / CSS
美国最大的香水连锁店官网:Perfumania
2016/08/15 全球购物
MySQL面试题
2014/01/12 面试题
计算机专业个人求职信范例
2013/09/23 职场文书
物理专业本科生自荐信
2014/01/30 职场文书
薪酬专员岗位职责
2014/02/18 职场文书
事假请假条范文
2014/04/11 职场文书
创业女性典型材料
2014/05/02 职场文书
运动会演讲稿100字
2014/08/25 职场文书
能让Python提速超40倍的神器Cython详解
2021/06/24 Python
win10电脑老是死机怎么办?win10系统老是死机的解决方法
2022/08/05 数码科技