javascript 函数调用规则


Posted in Javascript onAugust 26, 2009

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 相关文章推荐
表格 隔行换色升级版
Nov 07 Javascript
js中string转int把String类型转化成int类型
Aug 13 Javascript
jquery图形密码实现方法
Mar 11 Javascript
关于JSON与JSONP简单总结
Aug 16 Javascript
node.js实现复制文本到剪切板的功能
Jan 23 Javascript
angular6.x中ngTemplateOutlet指令的使用示例
Aug 09 Javascript
vue element table 表格请求后台排序的方法
Sep 28 Javascript
JavaScript栈和队列相关操作与实现方法详解
Dec 07 Javascript
VUE解决 v-html不能触发点击事件的问题
Oct 28 Javascript
JS document对象简单用法完整示例
Jan 14 Javascript
JavaScript 语句之常用 for 循环详解
Mar 29 Javascript
vue项目两种方式实现竖向表格的思路分析
Apr 28 Vue.js
JSON 入门指南 想了解json的朋友可以看下
Aug 26 #Javascript
javascript 继承实现方法
Aug 26 #Javascript
JS去除字符串的空格增强版(可以去除中间的空格)
Aug 26 #Javascript
JavaScript 获取用户客户端操作系统版本
Aug 25 #Javascript
JS 获取span标签中的值的代码 支持ie与firefox
Aug 24 #Javascript
jquery 表单进行客户端验证demo
Aug 24 #Javascript
JS 时间显示效果代码
Aug 23 #Javascript
You might like
PHP大批量插入数据库的3种方法和速度对比
2014/07/08 PHP
浅谈PHP中Stream(流)
2015/06/08 PHP
详解PHP对象的串行化与反串行化
2016/01/24 PHP
PHP获取路径和目录的方法总结【必看篇】
2017/03/04 PHP
dojo 之基础篇
2007/03/24 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
使用GruntJS构建Web程序之构建篇
2014/06/04 Javascript
JS实现的Select三级下拉菜单代码
2015/08/20 Javascript
jquery实现网页的页面平滑滚动效果代码
2015/11/02 Javascript
JavaScript蒙板(model)功能的简单实现代码
2016/08/04 Javascript
Ionic默认的Tabs模板使用实例
2016/08/29 Javascript
详解js类型判断
2018/05/22 Javascript
.vue文件 加scoped 样式不起作用的解决方法
2018/05/28 Javascript
JS实现全屏预览F11功能的示例代码
2018/07/23 Javascript
Vue中用props给data赋初始值遇到的问题解决
2018/11/27 Javascript
vue favicon设置以及动态修改favicon的方法
2018/12/21 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
小程序分页实践之编写可复用分页组件
2019/07/18 Javascript
jQuery pager.js 插件动态分页功能实例分析
2019/08/02 jQuery
详解element-ui级联菜单(城市三级联动菜单)和回显问题
2019/10/02 Javascript
[01:15:15]VG VS EG Supermajor小组赛B组胜者组第一轮 BO3第二场 6.2
2018/06/03 DOTA
PyQt5每天必学之创建窗口居中效果
2018/04/19 Python
python多线程分块读取文件
2019/08/29 Python
Vichy薇姿加拿大官网:法国药妆,全球专业敏感肌护肤领先品牌
2018/07/11 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?用contains来区分是否有重复的对象。还是都不用
2013/07/30 面试题
工程部主管岗位职责
2013/11/17 职场文书
化妆品店促销方案
2014/02/24 职场文书
自动一体化专业求职信
2014/03/15 职场文书
团日活动总结
2014/04/28 职场文书
机械专业求职信范文
2014/07/15 职场文书
医院领导班子查摆问题对照检查材料思想汇报
2014/10/08 职场文书
文明单位汇报材料
2014/12/24 职场文书
浅谈Python数学建模之数据导入
2021/06/23 Python
Python中非常使用的6种基本变量的操作与技巧
2022/03/22 Python