JavaScript 设计模式中的 this、call 和 apply(设计模式与开发实践 P3)

2023-09-15 01:01:32

2.1 this

javascript 的 this 总是指向一个对象,且指向的对象 基于函数的执行环境 动态绑定,而不是函数声明时的环境

this 作为对象的方法

函数 getNum 作为对象 obj 的方法被调用,this 指向对象 obj

var obj = {
	numb: 1,
	getNum: function(){
		alert(this === obj) // -> true
		alert(this.num) // -> 1
	}
}

this 作为普通函数

此时 this 总是指向全局对象,在浏览器中,这个全局对象就是 window

window.name = 'global'
var getName = function() {
	return this.name
}

getName() // 返回 global

这时就会遇到一个我们不想要的情况:

window.name = 'global'
var obj = {
	name: 'sven',
	getName: function(){
		return this.name;
	}
}

var getNameGlobal = obj.getName 
alert(getNameGlobal()) // 输出 global

我们可以通过设置一个变量来解决 (这部分内容存疑,但在代码行中是可实现的):

window.name = 'global'
var obj = {
	name: 'sven',
	that: this,
	getName: function() {
		return that.name;
	}
}

构造器调用

javascript 中没有类,但可以通过 new 运算符来从函数中构造对象:

var myClass = function(){
	this.name = 'sven'
}

var obj = new myClass();
alert(obj.name) // sven

不过需要注意的是,如果 function 显式返回一个对象,运算结果还是那个返回值

var myClass = function() {
	this.name = 'sven'
	return {
		name: 'anne'
	}
}

var obj = new myClass()
alert(obj.name) // anne

call 和 apply

用 call 和 apply 可以动态地改变传入函数的 this:

var obj = {
	name: 'sven'
	getName: function(){
		return this.name;
	}
}

var obj2 = { name: 'anne' }

alert(obj1.getName.call(obj2)) // anne

2.2 call 和 apply

call 和 apply 作用一模一样,只是传入参数的形式不同

var func = function(a, b, c){
	alert([a, b, c])
}
 
func.apply(null, [1, 2, 3]) // 参数以数组的形式发送,用的更多~
func.call(null, 1, 2, 3) // 参数一个一个传入

那么在 javascript 中 call 和 apply 有什么实际用途?

修正函数中的 this

document.getElementById('div1').onclick = function(){
	alert(this.id)
	var func = function(){
		alert(this.id)
	}
	func() // window.id => undefined
	func.call(this) // div1
}

模拟 bind 函数

Function.prototype.bind = function(ctx) {
	var self = this;
	return function(){
		return self.apply(ctx, arguments);
	}
}

var obj = { name: 'sven' }

var func = function(){
	alert(this.name)
}.bind(obj)

func(); // 输出 sven

借用其他对象的方法

如下这样,就可以通过借用其他构造函数来实现类似继承的效果了:

var A = function (name) {
  this.name = name;
};

var B = function () {
  A.apply(this, arguments);
};

B.prototype.getName = function () {
  return this.name;
};

var b = new B("sven");
console.log(b.getName());

另一个例子是借用一些实用类,这就使得一些本来不是数组的东西也可以使用数组的方法了:

(function () {
  var x = Array.prototype.push.apply(arguments, [4, 5, 6]);
  console.log(arguments);
})(1, 2, 3); // 添加新元素

(function () {
  var x = Array.prototype.slice.apply(arguments, [0, 1]);
  console.log(x);
})(1, 2, 3, 4, 5); // 转换成真的数组
更多推荐

数据结构与算法(C语言版)P1---算法效率

算法的效率:算法的时间复杂度和空间复杂度【本节目标】1.算法效率2.时间复杂度3.空间复杂度4.常见时间复杂度以及复杂oj练习1、算法效率1.1、如何衡量一个算法是的好坏如何衡量一个算法的好坏呢?比如斐波那契数列:longlongFib(intN){if(N<3)return1;returnFib(N-1)+Fib(N

MFC网络编程2——异步套接字

从上一节(MFC网络编程1——网络基础及套接字)中,我们了解了网络的部分基础知识以及套接字的使用,这一节,我们学习异步套接字的使用。Windows套接字在两种模式下执行I/O操作,阻塞模式和非阻塞模式。在阻塞模式下,在I/O操作完成前,执行操作的Winsock函数会一直等待下去,不会立即返回,例如,程序中调用了recv

分布式事务

1.分布式事务问题1.1.本地事务本地事务,也就是传统的单机事务。在传统数据库事务中,必须要满足四个原则:1.2.分布式事务分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如:跨数据源的分布式事务跨服务的分布式事务综合情况在数据库水平拆分、服务垂直拆分之后,一个业务操作通常要跨多个数据库、服务才能完成

上海亚商投顾:沪指失守3100点补缺口 华为概念股逆市活跃

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。一.市场情绪三大指数昨日继续调整,沪指失守3100点,深成指跌破万点大关,创业板指续创3年多以来新低。华为概念股逆市活跃,捷荣技术再度涨停,18个交易日累计涨超250%,光弘科技、荣联科技、天邑股份、常山北明等多股封板。

UOS QTextEdit设置换行和滚动条(bug自动换行时右侧个别字符被遮盖)

一、环境UOS_x86/QT5/C++二、qtextEdit换行设置下图在ui界面lineWrapMode这个参数可以设置换行相关:NoWrap是不换行、WidgetWidth是自动换行(按textEdit的宽度换行)、下面两个是可以自定义每行的宽度,如果选了这两个,就可通过下面LineWrapColumnOrWidt

运维面试宝典

【Linux基础篇】1.描述Linux运行级别0-6的各自含义0:关机模式1:单用户模式<==破解root密码2:无网络支持的多用户模式3:有网络支持的多用户模式(文本模式,工作中最常用的模式)4:保留,未使用5:有网络支持的X‐windows支持多用户模式(桌面)6:重新引导系统,即重启2.描述Linux系统从开机到

【无标题】

一、Vue脚手架搭建(一)安装与配置1.npmconfigsetregistryhttp://registry.npm.taobao.org/npminstall-g@vue/clivue--version//进入目录小白做毕设2024vuecreatevue2.输入cdvuenpmrunserve3.成功(二)结构解

代码变更风险可视化系统建设与实践

总第575篇2023年第027篇本文整理自美团技术沙龙第77期《美团亿级流量系统的质量风险防控和稳定性治理实践》。文章第一部分介绍了软件系统风险与变更;第二部分介绍了代码变更风险可视化系统的能力建设;第三部分介绍了整个系统在美团内部实践落地的情况;最后是对未来的规划和展望。希望对大家能有所帮助或启发。1软件系统风险与变

SMTP是什么?谈谈SMTP的含义

SMTP,即SimpleMailTransferProtocol,也称为简单邮件传输协议,是一种用于电子邮件传输的协议。它能够将邮件从发送者的电子邮件客户端传输到接收者的电子邮件服务器,并通过其他协议将邮件传递给接收者的电子邮件客户端。SMTP协议的作用是让邮件能够成功投递并发送到指定的收件人邮箱。蜂邮给大家说说:SM

【产品运营】如何提升B端产品的竞争力(上)

B端产品的核心竞争力不是只有产品功能丰富度、易用度这些维度,判断产品核心竞争力应该基于产品所定位解决的问题场景。B端产品的成交因素很多,包括产品本身、公司品牌、客情关系、成功案例、产品定价、客户成熟度、需求匹配度等,本文只谈产品本身。一、产品竞争力类型B端产品本身的核心竞争力不仅只有产品功能丰富度、易用度这些维度,判断

如何下载安装 WampServer 并结合 cpolar 内网穿透,轻松实现对本地服务的公网访问

文章目录前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1注册账号3.2下载cpolar客户端3.3登录cpolarwebui管理界面3.4创建公网地址4.固定公网地址访问前言Wamp是一个Windows系统下的Apache+PHP+Mysql集成安装环境,是一组常用来搭

热文推荐