当浏览器中添加新的API功能,尽管这个API提供了更多的功能和权限,我认为他们可能会给我的项目带来更多困惑,无论是API的问题还是项目编写的构想,我们都可以尝试去使用它,你一定会遇到不符合你项目程序的错误代码。使用try/catch运行这些API,它使代码更清洁、副作用少。
JavaScript中安全的调用函数方法
我们在控制台为用户输出一段话。
代码如下 | 复制代码 |
function attempt(fn, args, binding) { try { return fn.apply(binding, args); } catch(e) { console.log('Exception, fix me please', e); } } // Use it! attempt(function() { /* volatile stuff */ }, ['argOne', someVar], this); |
提供的功能,参数,并结合和你所有的设置。 你可以使用匿名函数,函数名,无论。 你不需要自己添加try/catch块到处。 没有什么突破性的在上面的 代码,但它的安全和方便!
在一个使用方法调用语法,像 obj.myFunction()或者 obj['myFunction'](),这时this的值为obj
这是事件处理代码中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> |
点击第一个按钮将会显示”btn”因为它是一个方法调用,this为所属的对象(按钮元素) 点击第二个按钮将显示”window”因为 buttonClicked是被直接调用的(不像 obj.buttonClicked().) 这和我们第三个按钮,将事件处理函数直接放在标签里是一样的.所以点击第三个按钮的结果是和第二个一样的.
使用像jQuery的JS库有这样的优点,当在jQuery里定义了一个事件处理函数,JS库会帮助重写this的值以保证它包含了当前事件源元素的引用,
代码如下 | 复制代码 |
//使用jQuery $('#btn1').click( function() { alert( this.id ); // jQuery ensures 'this' will be the button }); |
jQuery是如何重载this的值的呢?继续阅读
JSavacript函数调用规则3
如果我们想在不复制函数到一个方法而想重载this的值的时候,我们可以使用 myFunction.apply( obj ) 或 myFunction.call( obj ).
构造器
我不想深入研究在Javascript中类型的定义,但是在此刻我们需要知道在Javascript中没有类,而且任何一个自定义的类型需要一个初始化函数,使用原型对象(作为初始化函数的一个属性)定义你的类型也是一个不错的主义,让我们来创建一个简单的类型
代码如下 | 复制代码 |
//声明一个构造器 function ArrayMaker(arg1, arg2) { |
一个非常重要并值得注意的是出现在函数调用前面的new运算符,没有那个,你的函数就像全局函数一样,且我们创建的那些属性都将是创建在全局对象上(window),而你并不想那样,另一个话题是,因为在你的构造器里没有返回值,所以如果你忘记使用new运算符,将导致你的一些变量被赋值为 undefined.因为这个原因,构造器函数以大写字母开头是一个好的习惯,这可以作为一个提醒,让你在调用的时候不要忘记前面的new运算符.
带着这样的小心,初始化函数里的代码和你在其他语言里写的初始化函数是相似的.this的值将是你将创建的对象.
在没有通过明确所有者对象而直接调用的函数中,如myFunction(),将导致this的值成为默认对象(浏览器中的窗口)。
函数调用
让我们现在创建一个简单的对象,使用 makeArray函数作为它的一个方法,我们将使用json的方式来声明一个对象,我们也来调用这个方法
代码如下 | 复制代码 |
//creating the object var arrayMaker = { someProperty: 'some value here', make: makeArray }; //invoke the make() method arrayMaker.make('one', 'two'); // => [ arrayMaker, 'one', 'two' ] // alternative syntax, using square brackets arrayMaker['make']('one', 'two'); // => [ arrayMaker, 'one', 'two' ] |
看到这里的不同了吧,this的值变成了对象本身.你可能会疑问原始的函数定义并没有改变,为何它不是window了呢.好吧,这就是函数在JSavacript中传递的方式,函数在JavaScript里是一个标准的数据类型,确切的说是一个对象.你可以传递它们或者复制他们.就好像整个函数连带参数列表和函数体都被复制,且被分配给了 arrayMaker里的属性make,那就好像这样定义一个 arrayMaker:
代码如下 | 复制代码 |
var arrayMaker = { someProperty: 'some value here', make: function (arg1, arg2) { return [ this, arg1, arg2 ]; } }; |