javascript 函数调用的对象和方法


Posted in Javascript onJuly 01, 2010

如果你真正理解Javascript函数是如何调用工作的,那么就可以避免一些bug的发生;
首先让我们创建一个简单的函数,这个函数将在下文中使用,这个函数仅仅返回当前的this的值和两个提供的参数.

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

调用这个函数非常的简单,我们需要做的仅仅是:
makeArray('one', 'two');

返回值:=> [ window, 'one', 'two' ]
问题出现了,this的值怎么会变成了window?下面做个简单分析:
在Javascript里,有一个全局的对象, 那些看起来散落在你的脚本里的每一行代码,其实都被写在了一个全局对象的上下文里.在我们的例子中,其实那个makeArray 函数可以说不是一个松散的全局函数,而是全局对象的一个方法, 让我们返回来看浏览器,在这个环境里它的全局对象被映射到window对象.让我们来证明一下:
alert( typeof window.makeArray);

返回值:=> function

所有的这些意味着我们之前调用makeArray的方法是和下面调用的方法一样的,

window.makeArray('one', 'two');

返回值:=> [ window, 'one', 'two' ]

JavaScript函数调用规则1:在没有通过明确所有者对象而直接调用的函数中,如myFunction(),将导致this的值成为默认对象(浏览器中的窗口)。

现创建一个简单的对象,使用makeArray函数作为它的一个方法,我们将使用json的方式来声明一个对象,我们也来调用这个方法:

var arrayMaker = { 
someProperty: 'some value here', 
make: makeArray 
}; 
arrayMaker.make('one', 'two'); 
// 返回:=> [ arrayMaker, 'one', 'two' ] 
arrayMaker['make']('one', 'two'); 
// 返回:=> [ arrayMaker, 'one', 'two' ]

this的值变成了对象arrayMaker本身.你可能会疑问原始的函数定义并没有改变,为何它不是window了呢.函数是一个对象,你可以传递它们或者复制他们.就好像整个函数连带参数列表和函数体都被复制,且被分配给了arrayMaker里的属性make,那就好像这样定义一个arrayMaker:
var arrayMaker = { 
someProperty: 'some value here', 
make: function (arg1, arg2) {return [ this, arg1, arg2 ];} 
};

JavaScript函数调用规则2: 在一个使用方法调用语法,像 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; 
//返回值:=> btn1,它是一个方法调用,this为所属的对象(按钮元素) 
button2.onclick = function(){buttonClicked();}; 
//返回值:=> window ,因为buttonClicked()是被直接调用的(不像 obj.buttonClicked().) 这和我们第三个按钮,将事件处理函数直接放在标签里是一样的.所以点击第三个按钮的结果是和第二个一样,都是window. 
</script>

我们知道在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' ]

值得注意的是出现在函数调用前面的new运算符,没有它,函数就像全局函数一样,且我们创建的那些属性都将是创建在全局对象上(window),而你并不想那样,另一个话题是,因为在你的构造器里没有返回值,所以如果你忘记使用new运算符,将导致你的一些变量被赋值为 undefined.因为这个原因,构造器函数以大写字母开头是一个好的习惯,这可以作为一个提醒,让你在调用的时候不要忘记前面的new运算符.

Javascript函数调用规则3: 当你将函数用作初始化函数的时候,像MyFunction(),Javascript的运行时将把this的值指定为新建的对象.

Javascript 相关文章推荐
javascript模块化是什么及其优缺点介绍
Sep 02 Javascript
js创建对象的区别示例介绍
Jul 24 Javascript
jQuery+ajax实现文章点赞功能的方法
Dec 31 Javascript
微信小程序实现滑动删除效果
May 19 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
Jul 27 Javascript
vue.js或js实现中文A-Z排序的方法
Mar 08 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
Sep 20 Javascript
Vue表单控件绑定图文详解
Feb 11 Javascript
vue+iview动态渲染表格详解
Mar 19 Javascript
一百行JS代码实现一个校验工具
Apr 30 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
Mar 09 Javascript
JavaScript 去重和重复次数统计
Mar 31 Javascript
this和执行上下文实现代码
Jul 01 #Javascript
jquery.validate使用攻略 第五步 正则验证
Jul 01 #Javascript
jquery validate使用攻略 第四步
Jul 01 #Javascript
jquery.validate使用攻略 第三部
Jul 01 #Javascript
jquery.validate使用攻略 第二部
Jul 01 #Javascript
jQuery Validation插件remote验证方式的Bug解决
Jul 01 #Javascript
jquery.validate使用攻略 第一部
Jul 01 #Javascript
You might like
一个颜色轮换的简单例子
2006/10/09 PHP
用PHP将数据导入到Foxmail的实现代码
2010/09/05 PHP
PHP弹出对话框技巧详细解读
2015/09/26 PHP
javascript 屏蔽鼠标键盘的几段代码
2008/01/02 Javascript
传智播客学习之java 反射
2009/11/22 Javascript
中国地区三级联动下拉菜单效果分析
2012/11/15 Javascript
图片动画横条广告带上下滚动可自定义图片、链接等等
2013/10/20 Javascript
JavaScript中的异常捕捉介绍
2014/12/31 Javascript
jQuery使用EasyUi实现三级联动下拉框效果
2017/03/08 Javascript
VUE axios发送跨域请求需要注意的问题
2017/07/06 Javascript
jQuery Pagination分页插件_动力节点Java学院整理
2017/07/17 jQuery
Vue-cli创建项目从单页面到多页面的方法
2017/09/20 Javascript
React组件refs的使用详解
2018/02/09 Javascript
javascript+css实现进度条效果
2020/03/25 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
2020/11/02 Javascript
vue el-upload上传文件的示例代码
2020/12/21 Vue.js
mapboxgl实现带箭头轨迹线的代码
2021/01/04 Javascript
Python通过poll实现异步IO的方法
2015/06/04 Python
python实现批量图片格式转换
2020/06/16 Python
python 机器学习之支持向量机非线性回归SVR模型
2019/06/26 Python
深入了解Python iter() 方法的用法
2019/07/11 Python
学习和使用python的13个理由
2019/07/30 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
2019/08/29 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
Keras-多输入多输出实例(多任务)
2020/06/22 Python
python 代码运行时间获取方式详解
2020/09/18 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
德国在线订购鲜花:Fleurop
2018/08/25 全球购物
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
经贸日语毕业生自荐信
2013/11/03 职场文书
捐款倡议书范文
2014/02/02 职场文书
祖国在我心中演讲稿500字
2014/05/04 职场文书
2014年国庆节庆祝建国65周年比赛演讲稿
2014/09/21 职场文书
银行党的群众路线教育实践活动对照检查材料
2014/09/25 职场文书
求职信范文怎么写
2015/03/19 职场文书
四风之害观后感
2015/06/09 职场文书