不是我翻译的,但是觉得不错,为了分享,只好...

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"  οnclick="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"  οnclick="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的第一步。

转载于:https://www.cnblogs.com/island205/archive/2010/03/07/1680355.html

JavaScript函数 this调用规则相关推荐

  1. C++函数模板和普通函数的调用规则

    C++函数模板和普通函数的调用规则: 普通函数可以进行自动类型转换. 函数模板必须严格类型匹配. C++编译器优先考虑普通函数. 如果函数模板可以产生一个更好的匹配,那么选择模板. 可以通过空模板实参 ...

  2. 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)

    关于函数的调用规则(调用约定),大多数时候是不需要了解的,但是如果需要跨语言的编程,比如VC写的dll要delphi调用,则需要了解. microsoft的vc默认的是__cdecl方式,而windo ...

  3. 模板 (函数模板语法 ,类模板与函数模板的区别,:函数模板案例,普通函数与函数模板的区别,普通函数与函数模板调用规则,模板的局限性,类模板分文件编写.cpp,Person.hpp,类模板与友元)

    **01:函数模板语法: #include<iostream> using namespace std;//交换两个整型函数 void swapInt(int &a ,int &a ...

  4. C++ 函数匹配 重载函数的调用规则

    学习<C++ Primer>一书中,函数匹配这一节内容信息较多,现截取重点内容记录于此.便于你对本文内容更好的理解,你需对类型提升.算术类型转换以及顶层cosnt,底层const有一定的了 ...

  5. C++类中const函数与非const函数的调用规则

    class EX{public:void constFunction() const; }; 如上所示,通过将类成员函数声明为const,以表示这个函数不可以修改类中的成员变量. 建议将不可以修改数据 ...

  6. 类中const函数及非const函数的调用规则

    转自:点击打开链接 类中const函数及非const函数的调用规则 class Student { public:int getAge(){return m_age;}int getAge() con ...

  7. c++模板---1(模板概念,利用模板实现数组排序,函数模板调用规则)

    什么叫泛型编程?1. 参数类型化. 2. 模板 模板概念 c++提供了函数模板,所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表.这个通用函数就成为函数模 ...

  8. C++提高部分_C++普通函数与函数模板调用规则---C++语言工作笔记085

    然后我们再来看一下普通函数和函数模板的调用规则 可以看到有4个, 1.如果函数模板和普通函数都可以地调用的时候,优先调用普通函数 2.可以通过空模板参数列表,强制调用,函数模板 3.函数模板可以发生函 ...

  9. [译]深入理解JavaScript函数执行—调用栈,事件循环和任务等

    Web 开发者,或者前端工程师(我们更喜欢别人这么称呼)现如今几乎能做所有的工作,从扮演一个浏览器内部交互性的角色,到制作电脑游戏.桌面控件.跨平台手机应用,甚至还可以把它写在服务器端(最流行的是no ...

最新文章

  1. zeroclipboard 粘贴板的应用示例, 兼容 Chrome、IE等多浏览器
  2. JavaScript函数的各种调用模式
  3. 编写函数,可以接收任意多个整数并输出其中的最大值和所有整数之和。
  4. 包含数字和指定字符的正则表达式_Excel公式练习39: 求字符串中的数字组成的数能够被指定数整除的数的个数...
  5. 存储过程实现无限级分类(3)
  6. android应用对于内存的大小是有限制的,Android 的内存限制
  7. 配置文件空格丢失问题
  8. J2EEd 13个规范
  9. 使用javascript实现html页面直接下载网盘文件
  10. python关于csv的查询系统_使用Python对csv文件操作
  11. 51单片机学习笔记(2)——51单片机简介
  12. dataframe保存为txt_如何快速将TXT转换为SRT文件
  13. android service录音,android录音并上传至服务器
  14. 多台服务器连一个显示器如何切换,多台主机一台显示器怎么弄
  15. nginx多域名重定向到不同的二级域名
  16. 万有引力太阳系行星轨迹模拟
  17. 交换机和路由器技术-13-三层交换
  18. 元宇宙012 | 世界人工智能大会之元宇宙论坛:技术篇
  19. 算法题---leetcode-1
  20. 用php把图片合成视频,图片音乐合成视频 多张图片合成视频|图片合成视频软件...

热门文章

  1. codeforce 1311 C. Perform the Combo 前缀和
  2. windows上运行MapReduce出错(Failed to set permissions of path)
  3. 如何在Ubuntu系统的顶部标题栏中增加CPU/内存/网速实时监控的小控件
  4. 如何在linux程序中捕获异常信号
  5. Quartus II与 ModelSim功能仿真与后仿真扫盲(转)
  6. python3(一)数字Number
  7. 数据科学自动化_数据科学会自动化吗?
  8. 使用TensorFlow 2.0+和Keras实现AlexNet CNN架构
  9. 如果给你机会,阿里巴巴的中层职位和马云的专属司机,你怎么选?
  10. 贷款,别相信这些人!