本文摘要:http://www.liaoxuefeng.com/

在一个对象中绑定函数,称为这个对象的方法。

在JavaScript的中,对象的定义是这样的:

var xiaoming = {name: '小明',birth: 1990
};

但是,如果给我们xiaoming绑定一个函数,就可以做更多的事情比如,写个。age()方法,报道查看xiaoming的年龄:

var xiaoming = {name: '小明',birth: 1990,age: function () { var y = new Date().getFullYear(); return y - this.birth; } }; xiaoming.age; // function xiaoming.age() xiaoming.age(); // 今年调用是25,明年调用就变成26了 

绑定到对象上的函数称为方法,和普通函数也没啥区别,但是在它内部使用了一个this关键字,这个东东是什么?

在一个方法内部,this是一个特殊变量,它始终指向当前对象,就是也。xiaoming这个变量。所以,this.birth可以拿到xiaomingbirth属性。

让我们拆开写:

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决定,在严格的模式下让函数的this指向undefined,因此,在严格的模式下,你会得到一个错误:

'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了!(在非严格模式下,它重新指向全局对象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;,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。

应用

虽然在一个独立的函数调用中,根据是否是严格的模式,this指向undefinedwindow,不过,还是我们可以控制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()

var count = 0;
var oldParseInt = parseInt; // 保存原函数window.parseInt = function () { count += 1; return oldParseInt.apply(null, arguments); // 调用原函数 }; // 测试: parseInt('10'); parseInt('20'); parseInt('30'); count; // 3

转载于:https://www.cnblogs.com/Sea1ee/p/7085458.html

方法 -------JavaScript相关推荐

  1. 百度的一个Ajax跨域方法 JavaScript是没有域的限制

    baidu的通行证处理都是在二级域名passport.baidu.com中处理的,但是baidu很多地方登录都好像是用ajax处理的,他是怎么做的呢?研究了一下,发现一个小技巧. 在http://zh ...

  2. html number方法,JavaScript Number 对象

    JavaScript Number 对象 JavaScript 只有一种数字类型. 可以使用也可以不使用小数点来书写数字. JavaScript 数字 JavaScript 数字可以使用也可以不使用小 ...

  3. html5创建对象的方法,JavaScript面向对象-使用工厂方法和构造函数方法创建对象...

    在上一篇文章中我们介绍了JavaScript简单对象的创建方法,简单js对象的最大问题是由于没有类的约束,无法实现对象的重复利用,并且没有一种约定,在操作时会带来问题.所以人们从设计模式中借用了一种工 ...

  4. Jquery取得iframe中元素的几种方法Javascript Jquery获取Iframe的元素、内容或者ID,反之也行!...

    query取得iframe中元素的几种方法 在iframe子页面获取父页面元素 代码如下: $('#objId', parent.document); // 搞定... 在父页面 获取iframe子页 ...

  5. 回调函数与回调地狱及其解决方法 | JavaScript

    JavaScript中的回调函数与回调地狱及其解决方法 以下为整理的思维导图 图片版+文字版 文末附有参考文章链接 知识点思维导图版 一.什么是回调函数 1.MDN的定义 回调函数是作为参数传给另一个 ...

  6. js判断json有没有某值_JS中判断JSON数据是否存在某字段的方法 JavaScript中判断json中是否有某个字段...

    方式一 !("key" in obj) 方式二 obj.hasOwnProperty("key")  //obj为json对象. 实例: var jsonwor ...

  7. Functional vs OOP vs Procedural三种方法 JavaScript 示例

    #有什么问题? 当谈到编写好的代码时,您可以深入探讨关于好的代码到底是什么样子以及您应该遵循哪种编程范式的高度哲学讨论. 不过,本文(和视频,见上文)不会参与这些讨论 - 相反,我们将深入探讨三种非常 ...

  8. html插入地图的方法,JavaScript接入百度地图API的方法步骤

    一.百度地图API接入 1.搜索百度地图开发平台 2.注册百度账号 3.登陆并申请成为开发者 4.在百度地图开发平台的首页选择控制台,在控制台中创建应用 创建好应用以后就能在控制台我的应用中看到这个应 ...

  9. 快速上手 JavaScript 点击事件click的几种使用方法 (javascript红皮书二刷 - Ch13.2 事件处理程序)

    文章目录 onclick 属性 使用 js 给 onclick 属性赋值 元素上设置多个事件监听器 addEventListener onclick 属性 当你编写 HTML + JavaScript ...

最新文章

  1. UML基本架构建模--获取类
  2. Kubernetes的yaml文件中的command使用
  3. spring学习(32):使用junit4测试
  4. Encapsulate Collection(封装集合)
  5. P1420 最长连号(python3实现)
  6. Cs231N_学习笔记
  7. OLED电视出现烧屏问题 LG电子被判赔偿消费者16万澳元
  8. NUC1077 Humble Numbers【数学计算+打表】
  9. 终于购入Mac mini,发现HDMI接口与显示器不兼容,网购了一个VGA转换插头
  10. mysql as 后面字段,mysql 字段as详解及实例代码
  11. Linux查看磁盘是否被占满,怎么查看Linux磁盘空间是否满了?
  12. 怎么修改打印机服务器权限,Win7如何设置网络打印机管理权限
  13. 【笔记】wincap收集并统计网络流量
  14. 用Python批量操作文件
  15. fiddler证书安装
  16. 【springboot】报错Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No conve
  17. 架构设计分布式数据结构与算法面试题(2020最新版)
  18. 中国计算机科学院士,盘点!获奖者中,84位院士、10位国家最高科学技术奖得主,高校科学家表现出色...
  19. netcat常用命令
  20. 王爽 汇编语言 第二章 实验一

热门文章

  1. c语言实现队列基本算法,【算法】队列的C语言实现
  2. apollo local 模式_「架构」 - 配置中心 Apollo基本使用
  3. Golang实践录:我的工具包
  4. 我的docker随笔9:docker在centos上的安装
  5. Oracle删除当前用户下的所有表、视图、序列、函数、存储过程、包
  6. 【maven】maven dependencyManagement 锁定Jar包版本
  7. 【Elasticsearch】使用 Elasticsearch 轻松进行文本分类
  8. 【Elasticsearch】Elasticsearch 悬空索引
  9. Registry学习资料
  10. 81-spark异常总结1