JavaScript中5种调用函数的方法
前端之家 收集整理的这篇文章主要介绍了
JavaScript中5种调用函数的方法 ,
前端之家 小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_502 _0@这篇文章 详细的介绍了Javascript中各种函数 调用 的方法 及其原理,对于理解JavaScript的函数 有很大的帮助!
@H_
502 _0@
JavaScript,调用 函数 的5种方法
@H_
502 _0@一次又一次的,我发现,那些有bug的Javascript
代码 是由于没有真正理解Javascript
函数 是如何工作而导致的(顺便说一下,许多那样的
代码 是我写的).JavaScript拥有
函数 式编程的特性,当我们选择面对它的时候,这将成为我们前进的阻碍.
@H_
502 _0@作为初学者,我们来测试五种
函数 调用 的
方法 ,从表面来看我们会认为那些
函数 与C#中
函数 的作用非常相似,但是我们一会儿可以看到还是有非常重要的不同的地方的,忽视这些差异无疑会导致难于跟踪的bug。首先让我们创建一个简单的
函数 ,这个
函数 将在将在下文中使用,这个
函数 仅仅返回当前的this的值和两个提供的参数.
@H_
502 _0@<div class="codetitle">
<a style="CURSOR: pointer" data="87475" class="copybut" id="copybut87475" onclick="doCopy('code87475')"> 代码 如下: <div class="codebody" id="code87475">
<script type="text/javascript">
function makeArray(arg1,arg2){
return [ this,arg1,arg2 ];
}
@H_
502 _0@最常用的
方法 ,但不幸的,全局的
函数 调用
当我们学习Javascript时,我们了解到如何用上面示例中的语法来定义
函数 。,我们也知道
调用 这个
函数 非常的简单,我们需要做的仅仅是:
[ window,'one','two' ]
Wait a minute. What's that window
alert( typeof window.methodThatDoesntExist );
// => undefined
alert( typeof window.makeArray);
// =>
window.makeArray('one','two' ]
@H_
502 _0@我说最普遍的
调用 方法 是不幸的是因为它导致我们声明的
函数 默认是全局的.我们都知道全局成员不是编程的最佳实践.这在JavaScript里是特别的正确,在JavaScript中避免使用全局的成员,你是不会为之后悔的.
@H_
502 _0@
JavaScript函数 调用 规则1
在没有通过明确所有者对象而直接
调用 的
函数 中,如myFunction(),将导致this的值成为默认对象(浏览器中的窗口)。
@H_
502 _0@
@H_
502 _0@让我们现在创建一个简单的对象,使用 makeArray
函数 作为它的一个
方法 ,我们将使用json的方式来声明一个对象,我们也来
调用 这个
方法
//invoke the make() method
arrayMaker.make('one','two');
// => [ arrayMaker,'two' ]
// alternative
Syntax ,using square brackets
arrayMaker['make']('one','two' ]
@H_
502 _0@看到这里的不同了吧,this的值变成了对象本身.你可能会疑问原始的
函数 定义并没有改变,为何它不是window了呢.好吧,这就是
函数 在JSavacript中传递的方式,
函数 在JavaScript里是一个标准的数据类型,确切的说是一个对象.你可以传递它们或者复制他们.就好像整个
函数 连带参数列表和
函数 体都被复制,且被分配给了 arrayMaker里的
属性 make,那就好像这样定义一个 arrayMaker:
@H_
502 _0@
JavaScript函数 调用 规则2
@H_
502 _0@在一个使用
方法 调用 语法,像 obj.myFunction()或者 obj['myFunction'](),这时this的值为obj
@H_
502 _0@这是事件处理
代码 中bug的主要源头,看看这些例子
<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(); };
@H_
502 _0@点击第一个按钮将会
显示 ”btn”因为它是一个
方法 调用 ,this为所属的对象(按钮元素) 点击第二个按钮将
显示 ”window”因为 buttonClicked是被直接
调用 的(不像 obj.buttonClicked().) 这和我们第三个按钮,将事件处理
函数 直接放在
标签 里是一样的.所以点击第三个按钮的结果是和第二个一样的.
使用像jQuery的JS库有这样的优点,当在jQuery里定义了一个事件处理
函数 ,JS库会帮助重写this的值以保证它包含了当前事件源元素的引用,
jQuery是如何重载this的值的呢?继续阅读
@H_
502 _0@另外两个:apply()和call()
@H_
502 _0@你越多的使用JavaScript的
函数 ,你就越多的发现你需要传递
函数 并在不同的上下文里
调用 他们,就像Qjuery在事件处理
函数 里所做的一样,你往往经常需要重置this的值.记住我告诉你的,在Javascript中
函数 也是对象,
函数 对象包含一些预定义的
方法 ,其中有两个便是apply()和call(),我们可以使用它们来对this进行重置.
[ gasGuzzler,'two' ]
makeArray.call( gasGuzzler,'two' );
// => [ gasGuzzler,'two' ]
@H_
502 _0@这两个
方法 是相似的,不同的是后面的参数的不同,Function.apply()是使用一个数组来传递给
函数 的,而Function.call()是将这些参数独立传递的,在实践中你会发现apply()在大多数情况下更方便.
@H_
502 _0@
JSavacript函数 调用 规则3
@H_
502 _0@如果我们想在不复制
函数 到一个
方法 而想重载this的值的时候,我们可以使用 myFunction.apply( obj ) 或 myFunction.call( obj ).
@H_
502 _0@构造器
@H_
502 _0@我不想深入研究在Javascript中类型的定义,但是在此刻我们需要知道在Javascript中没有类,而且任何一个
自定义 的类型需要一个初始化
函数 ,使用原型对象(作为初始化
函数 的一个
属性 )定义你的类型也是一个不错的主义,让我们来创建一个简单的类型
var am = new ArrayMaker( 'one','two' );
var other = new ArrayMaker( 'first','second' );
am.getArray();
// => [ am,'two' ]
@H_
502 _0@一个非常重要并值得注意的是出现在
函数 调用 前面的new运算符,没有那个,你的
函数 就像全局
函数 一样,且我们创建的那些
属性 都将是创建在全局对象上(window),而你并不想那样,另一个话题是,因为在你的构造器里没有返回值,所以如果你忘记使用new运算符,将导致你的一些变量被赋值为 undefined.因为这个原因,构造器
函数 以大写字母开头是一个好的习惯,这可以作为一个提醒,让你在
调用 的时候不要忘记前面的new运算符.
@H_
502 _0@带着这样的小心,初始化
函数 里的
代码 和你在其他语言里写的初始化
函数 是相似的.this的值将是你将创建的对象.
@H_
502 _0@
Javascript函数 调用 规则4
@H_
502 _0@当你将
函数 用作初始化
函数 的时候,像MyFunction(),Javascript的运行时将把this的值指定为新建的对象.
@H_
502 _0@我希望理解各种
函数 调用 方式的不同会使你的Sjavacript
代码 远离bugs,有些这样的bug会确保你总是知道this的值是避免他们第一步。