参考:js教程 方法
在一个方法内部,this
是一个特殊变量,它始终指向当前对象,也就是xiaoming
这个变量。所以,this.birth
可以拿到xiaoming
的birth
属性。
让我们拆开写:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25, 正常结果
getAge(); // NaN
单独调用函数getAge()
怎么返回了NaN
?请注意,我们已经进入到了JavaScript的一个大坑里。
JavaScript的函数内部如果调用了this
,那么这个this
到底指向谁?
答案是,视情况而定!
如果以对象的方法形式调用,比如xiaoming.age()
,该函数的this
指向被调用的对象,也就是xiaoming
,这是符合我们预期的。
如果单独调用函数,比如getAge()
,此时,该函数的this
指向全局对象,也就是window
。
坑爹啊!
更坑爹的是,如果这么写:
var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN
也是不行的!要保证this
指向正确,必须用obj.xxx()
的形式调用!
由于这是一个巨大的设计错误,要想纠正可没那么简单。ECMA决定,在strict模式下让函数的this
指向undefined
,因此,在strict模式下,你会得到一个错误:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
};
var fn = xiaoming.age;
fn(); // Uncaught TypeError: Cannot read property 'birth' of undefined
这个决定只是让错误及时暴露出来,并没有解决this
应该指向的正确位置。
有些时候,喜欢重构的你把方法重构了一下:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - this.birth;
}
return getAgeFromBirth();
}
};
xiaoming.age(); // Uncaught TypeError: Cannot read property 'birth' of undefined
结果又报错了!原因是this
指针只在age
方法的函数内指向xiaoming
,在函数内部定义的函数,this
又指向undefined
了!(在非strict模式下,它重新指向全局对象window
!)
修复的办法也不是没有,我们用一个that
变量首先捕获this
:
'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var that = this; // 在方法内部一开始就捕获this
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - that.birth; // 用that而不是this
}
return getAgeFromBirth();
}
};
xiaoming.age(); // 25
用var that = this;
,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。
apply
虽然在一个独立的函数调用中,根据是否是strict模式,this
指向undefined
或window
,不过,我们还是可以控制this
的指向的!
要指定函数的this
指向哪个对象,可以用函数本身的apply
方法,它接收两个参数,第一个参数就是需要绑定的this
变量,第二个参数是Array
,表示函数本身的参数。
用apply
修复getAge()
调用:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
另一个与apply()
类似的方法是call()
,唯一区别是:
-
apply()
把参数打包成Array
再传入; -
call()
把参数按顺序传入。
比如调用Math.max(3, 5, 4)
,分别用apply()
和call()
实现如下:
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
对普通函数调用,我们通常把this
绑定为null
。
装饰器
利用apply()
,我们还可以动态改变函数的行为。
JavaScript的所有对象都是动态的,即使内置的函数,我们也可以重新指向新的函数。
现在假定我们想统计一下代码一共调用了多少次parseInt()
,可以把所有的调用都找出来,然后手动加上count += 1
,不过这样做太傻了。最佳方案是用我们自己的函数替换掉默认的parseInt()
:
'use strict'; var count = 0; var oldParseInt = parseInt; // 保存原函数 window.parseInt = function () { count += 1; return oldParseInt.apply(null, arguments); // 调用原函数 };
相关推荐
不过,由于【标题】中提供了文档的名称——"JavaScript函数式编程.pdf",我可以根据这个名称扩展出关于JavaScript函数式编程的知识点。 JavaScript函数式编程的知识点非常丰富,涉及很多方面的内容,下面将详细介绍...
以上就是在JavaScript中实现函数动态调用的几种常见方法,每种方法都有其适用的场景。需要注意的是,使用eval()函数虽然方便,但会带来安全风险和性能问题,因为它会执行任意的JavaScript代码。因此,在安全性要求较...
总之,JavaScript函数参数使用带参数名的方式赋值传入的方法是一种提高代码可读性和灵活性的优秀实践。它减少了因参数顺序或缺失导致的错误,使代码结构更加清晰,同时为参数管理提供了更多的控制选项。对于需要编写...
C#与JAVASCRIPT函数的相互调用 C#调用JAVASCRIPT函数的调用 JAVASCRIPT调用C#函数的调用
总结而言,JS函数式编程指南为读者提供了一种途径,借助于JavaScript这种广泛使用的编程语言,去理解和掌握函数式编程的核心概念和实践技巧。这本指南不仅涵盖了函数式编程的基础理论,还详细介绍了如何在实际开发中...
而《JavaScript函数式.zip》可能是一份关于JavaScript函数式编程的资料集合,函数式编程是一种编程范式,强调使用函数和避免改变状态。其中可能涵盖以下知识点: 1. **纯函数**:理解纯函数的定义,即给定相同的...
"java调用js方法.doc"很可能是详细描述如何从Java调用JS函数的步骤和示例。 在实际应用中,Java代码可能会通过Ajax发送一个请求到服务器,服务器解析请求后调用对应的JS函数,例如在"des.js"中执行解密操作,然后将...
假设前台页面的JS脚本标签中有如下函数: [removed] function A() { alert(hello word!); } [removed] 那么在这个页面的后台代码可以这样去实现在C#后台调用前台这个A()函数; 首先在前台拖放一个ItlResult...
- 这里的回调函数用于处理JavaScript函数的异步返回结果,如果需要同步获取结果,可以使用`QWebEngineScript`来注册一个全局JavaScript对象,然后通过该对象调用JavaScript函数。 2. **JavaScript调用QT函数**: ...
在JavaScript的常用库中,我们可以找到许多方便的公共方法,这些方法极大地提高了开发效率。 一、JavaScript常用函数 1. 数组操作函数 - `push()`: 向数组末尾添加一个或多个元素,并返回新长度。 - `pop()`: ...
JavaScript函数式编程是一种编程范式,它强调使用函数来组织代码,将计算视为一系列惰性求值的操作。Underscore.js是一个轻量级的JavaScript实用库,它为开发者提供了大量函数式编程工具,使得在JavaScript中实践...
在 JS 中,有四种主要的函数调用模式,分别是:普通函数调用、方法调用、构造函数调用和apply/call调用。下面我们将详细探讨这些调用模式。 1. **普通函数调用**: 这是最常见的情况,函数作为一个独立的实体被执行...
KETTLE中的JavaScript内嵌方法 KETTLE是一个开源的商业智能工具,提供了多种方式来处理和分析数据。其中,JavaScript是一种常用的脚本语言,用于在KETTLE中执行各种操作。在KETTLE中,JavaScript可以用于实现各种...
本书专门介绍JavaScript函数式编程的特性。 全书共9章,分别介绍了JavaScript函数式编程、一等函数与Applicative编程、变量的作用域和闭包、高阶函数、由函数构建函数、递归、纯度和不变性以及更改政策、基于流的...
要从C++调用JavaScript函数,可以使用`QWebView`的`page()->mainFrame()`方法获取`QWebFrame`对象,然后调用其`evaluateJavaScript()`函数。例如,如果你有一个名为`myJSFunction`的JavaScript函数,可以这样调用:...
JavaScript(简称JS)函数式编程是一种编程范式,它强调将计算视为函数的组合,而不是状态的变化或指令的序列。这种编程风格可以帮助开发者编写出更简洁、可读性更强、易于测试和维护的代码。本指南将深入探讨JS函数...
web前端javascript常用的的公共处理函数大全,性能较好。
这些方法可以在实际项目中应用,例如在父页面中调用 iframe 子页面的 js 函数来实现某些操作,或者在 iframe 子页面中调用父页面的 js 函数来实现某些操作。 相关知识点 1. iframe 子父页面调用 js 函数的示例 2. ...
本书专门介绍JavaScript函数式编程的特性。 全书共9章,分别介绍了JavaScript函数式编程、一等函数与Applicative编程、变量的作用域和闭包、高阶函数、由函数构建函数、递归、纯度和不变性以及更改政策、基于流的...
JavaScript函数库是Web开发中不可或缺的部分,它们提供了一系列预先封装好的功能,可以帮助开发者高效地完成各种任务,如动画处理、事件处理、数据管理、Ajax通信等。本"JavaScript函数库查询手册"旨在为开发者提供...