JS-12-关键字this、apply()、call()

一、对象的方法

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

示例:

1、对象:

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

2、给xiaoming绑定一个函数。比如,写个age()方法,返回xiaoming的年龄:

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

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

二、this关键字

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

function getAge() {var y = new Date().getFullYear();return y - this.birth;
}var xiaoming = {name: '小明',birth: 1990,age: getAge // age获取整个getAge这个函数的代码
};xiaoming.age(); // 25, 正常结果
getAge(); // NaN

问题来了:单独调用函数getAge()怎么返回了NaN。

因为这个JavaScript的函数内部调用了this,而这个this到底指向谁,视情况而定:

1、如果以对象的方法形式调用,比如xiaoming.age(),该函数的this指向被调用的对象,也就是xiaoming,这是符合我们预期的。

2、如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window。

更坑爹的是,如果这么写:

var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN

也是不行的!要保证this指向正确,必须用obj.xxx()的形式调用

3、方法重构

'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!)

纠正的方式:

1、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

这个决定只是让错误及时暴露出来,治标不治本。

2、方法重构

我们用一个that变量首先捕获this:

'use strict';var xiaoming = {name: '小明',birth: 1990,age: function () {var that = this; // 在方法内部一开始就捕获thisfunction getAgeFromBirth() {var y = new Date().getFullYear();return y - that.birth; // 用that而不是this}return getAgeFromBirth();}
};xiaoming.age(); // 25

var that = this;,你就可以放心地在方法内部定义其他函数

三、apply方法-控制this的指向

在一个独立的函数调用中,根据是否是strict模式,this指向undefined或window。

要指定函数的this指向哪个对象,可以用函数本身的apply方法

apply方法接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。

 

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, 参数为空

四、call方法-控制this的指向

另一个与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');
console.log('count = ' + count); // 3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/745127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SwiftUI的context Menu

SwiftUI的 context Menu 现在来演示一下如何使用 SwiftUI 的 Context Menu 。 代码: import SwiftUIstruct ContextMenuBootCamp: View {State var bgColor: Color .purplevar body: some View {VStack(alignment: .leading, spacing: 10.0) {Image(systemName: …

LLVM-3.5 —— 01记,编译 LLVM 3.5.0 clang and clang-query

包括编译:clang clang-tools-extra 0, prepare env sudo apt install llvm sudo apt install clang 使用最新的g 会出错。 1, source code $ git clone --recursive $ cd llvm-project $ git checkout llvmorg-3.5.0 $ cp -r ./clang ./llvm/tools/ $ mkdir llv…

冥想与AI:打造定制的放松体验

如今,在浏览网页或社交网络时,您似乎很难对一条条心理健康信息无动于衷。遇到这种情况的可不只是您。当今不断变化的时代给人们平添压力,企业纷纷利用智能技术满足人们的减压需求,让人们的生活多一些平和从容。 冥想就是一种练习呼…

高效Go编程: encoding/csv标准库深度解析

高效Go编程: encoding/csv标准库深度解析 引言了解encoding/csv库CSV文件的基本结构encoding/csv库的核心功能应用场景 读取CSV文件基本步骤代码示例处理不同的分隔符错误处理 处理CSV数据数据解析代码示例处理不规则数据代码示例 写入CSV文件基本步骤代码示例自定义设置错误处…

Vue组件之间的通信方式

文章目录 组件间通信的概念组件间通信的分类组件间通信的方案父组件将方法传递给子组件(props)子组件向父组件传值(emit)通过 ref 属性获取DOM元素EventBus p a r e n t 或 parent 或 parent或 root a t t r s 与 attrs 与 attrs与 listeners provide 与…

Kotlin编程权威指南学习知识点预览

一、变量、常量和类型: 变量、常量以及 Kotlin 基本数据类型。变量和常量在 应用程序中可用来储值和传递数据。类型则用来描述常量或变量中保存的是什么样的数据。 1、声明变量: // 变量定义关键字 —— 变量名 —— 类型定义 —— 赋值运算符 —— 赋值var na…

cesium wall 扩散墙(动态立体墙效果 Primitive 方法)

cesium wall 扩散墙(动态立体墙效果)以下为源码直接复制可用 1、实现思路 1、此效果运用cesium 中 Primitive 方法,通过传入中心点、半径、顶点数、颜色来进行加载。 2、运用 Math 方法 对传进来的中心点、半径、定点数,来计算个顶点经纬度。 3、通过Primitive 方法中upda…

643.子数组最大平均数

题目:给你一个由 n 个元素组成的整数数组 nums 和一个整数k。 找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数。 任何误差小于10^-5 的答案都将被视为正确答案。 解题思路:规定了子数组的长度为k,因此可以通过寻找子…

洛谷——P1352 没有上司的舞会

题目描述 某大学有 n 个职员,编号为1…n。 他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。 现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 ri​,但…

【MySQL】深入解析索引实现原理

文章目录 1、索引介绍2、索引分类2.1、数据结构HashB Tree 2.2、存储方式聚簇索引非聚簇索引 2.3、功能特性主键索引唯一索引普通索引 2.4、字段数量单列索引多列索引 3、最佳实践3.1、索引覆盖3.2、回表操作3.3、最左匹配原则3.4、索引下推 1、索引介绍 对于MySQL数据库来说…

笔试题:小红的循环小数 数论 欧拉 快速幂 小费马定理

小红的循环小数 众所周知,所有的无限循环小数都可以写成分数的形式 小红想让你判断循环节长度为k的无限循环小数的分母是否可能是p。你能帮帮她吗? 共有q次询问。 输入描述 第一行输入一个正整数 q q q,代表询问次数。 接下来的 q q q行&…

Tensorflow笔记(二):常用函数2、激活函数、优化器等、神经网络模型实现(商品销量预测)

import tensorflow as tf import numpy as np from tqdm import tqdm# ----------------------------- tensor常用函数2 ----------------------------------- a tf.constant([1, 2, 3, 1, 2]) b tf.constant([0, 1, 3, 4, 5]) c tf.where(tf.greater(a, b), a, b) # 若a&g…

计算机毕业设计-springboot+vue前后端分离电竞社交平台管理系统部分成果分享

4.5系统结构设计 本系统使用的角色主要有系统管理员、顾客、接单员,本系统为后台管理系统,游客用户可以经过账号注册,管理员审核通过后,用账号密码登录系统,查看后台首页,模块管理(顾客信息&am…

mysql重构

力扣题目链接 列转行 SELECT product_id, store1 store, store1 price FROM products WHERE store1 IS NOT NULL UNION SELECT product_id, store2 store, store2 price FROM products WHERE store2 IS NOT NULL UNION SELECT product_id, store3 store, store3 price FROM p…

全栈的自我修养 ———— js中的复制api

通常用于可以禁止用户复制或者在复制的内容后面添加版权信息等 一、代码二、展示1、访问粘贴板的内容2、替换复制内容3、在复制内容的后面添加版权信息4、监听粘贴事件 一、代码 <body><div class"demo">不可以被复制</div><div class"de…

如何从任何文档生成指令数据集以进行LLM微调

使用轻量级库经济地生成高质量的合成数据集 大型语言模型 &#xff08;LLMs&#xff09; 是功能强大的通用工具&#xff0c;但它们通常缺乏特定于领域的知识&#xff0c;这些知识通常存储在企业存储库中。 使用您自己的数据微调自定义LLM可以弥合这一差距&#xff0c;而数据准…

【Shiro反序列化漏洞】Shiro-550反序列化漏洞复现

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

了解下索引的几棵树?

二叉树 二叉搜索树最好的情况性能是O(logn)&#xff0c;最坏情况是O(n) 红黑树 它的时间复杂度是O(logn)&#xff0c;但是在数据量特别大的时候&#xff0c;树会特别高&#xff0c;就会遍历很多层级&#xff0c;对性能影响较大 BTree B树是一种多叉路衡查找树&#xff0c;相对于…

解决NVM安装Node失败:淘宝NPM镜像HTTPS证书到期及源切换指南

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

如果利用AOP/Aspect来修改方法的入参

问题描述&#xff1a; 最近项目代码过三方测试&#xff08;国企项目&#xff09;&#xff0c;在一系列代码扫描审计检查下&#xff0c;代码发现一部分修改&#xff0c;例如请求参数发生了编码/加密&#xff0c;导致后台需要对请求的参数进行解码/解密&#xff0c;后端那么接口&…