搞懂Js中的this,call和apply方法

news/2024/7/7 19:16:27

为了更好的看懂这篇文章,建议先要理解js对象的原型和原型链相关的知识,若不了解,可以看上一篇文章《js对象的构造函数与原型》

this的理解

  • 在全局中使用this,this为window对象
  • 谁调用了对象中属性,this就是谁
  • this.xxx调用属性的时候,会沿着原型链查找xxx属性

案例如下:

	var width = 200,name = 'window'
	Object.prototype.color = 'red'
	Object.prototype.findName = function(){
		console.log(this.name)
	}

	Object.prototype.findWidth = function(){
		console.log(this.width)
	}

	Person.prototype.height = 180

	function Person(){
		this.name = 'Person'

		this.sayName = function(){
			console.log(this.name)
		}

		this.sayHeight = function(){
			console.log(this.height)
		}

		this.sayColor = function(){
			console.log(this.color)
		}

		this.sayWidth = function(){
			console.log(this.width)
		}

		this.getName = function(){
			this.findName()
		}

		this.getWidth = function(){
			this.findWidth()
		}

	} 

	var per = new Person()
	per.sayName() //Person
	per.sayHeight() //180
	per.sayColor() //red 
	per.getName() //Person
	per.sayWidth() //undeinfed
	per.getWidth() //undeinfed
	this.findWidth() //200
	this.findName() //window
	console.log(this.width) //200

控制台打印结果:
在这里插入图片描述

案例分析

per.sayName() //Person

分析:per为构造函数Person构造的对象,自身就带有name属性,所以per.sayName()方法中,console.log(this.name),this代表的就是per自身,this.name就是等于是per.name,即为“Person”.

per.sayHeight() //180

分析:per.sayHeight()中,console.log(this.height),this指的也是per,但是per对象自身没有height属性,但此时,会根据per对象的原型链开始寻找是否存在height属性,因为构造函数Person.prototype.height = 180,因此这里this.height会取Person原型中的height,即为180.

per.sayColor() //red

分析:per.sayColor()同理,打印的是this.color, this指得也是per,但是它自身没有color属性,他的原型也没有color属性,此时,会继续沿着原型链寻找,是否有color属性,最终在构造Object的原型中寻找到color属性,因此per对象也会继承该属性,因此this.color为 “red”.

per.getName() //Person

分析:在per.getName()中调用this.findName(),显然per对象是没有findName方法的,依然更具原型链寻找,在Object原型中找到findName()方法,所以per也能调用findName()方法,根据"谁调用,this就是谁的原则",此时this为per,因此findName()中的console.log(this.name),打印的即为per.name,所以输出结果为 “Peroson”.

per.sayWidth() //undeinfed

分析:per.sayWidth(),打印的是this.width,但是在per对象和他的原型链中,都没有找到width属性,因此打印的结果为undefined.

per.getWidth() //undeinfed

分析:根据原型链查找原则,per.getWidth()实际调用的是Object原型中的findWith()方法,this指的是per对象,但是在per对象以及他的原型链都没有找到width属性,因此findwith()中的console.log(this.width)的打印结果为undefined.

this.findWidth() //200

分析:根据“在全局中,this就是window”的原则,this.findWidth()即等于window.findWidth().
但是window对象没有findWidth()方法,同样会沿着原型链查找findWidth方法,最后在最终的构造函数Object对象原型中找到findWidth方法,所以window对象也能调用findWidth()方法。findWidth()方法中打印的是this.width,已知this即为window,所以等于window.width 即等于变量width,所以最终输出的结果为200.

this.findName() //window

分析:与上述分析同理,this.findName 中的 this.name等于 window.name 即为name变量,所以输出 “window”

console.log(this.width) //200

分析:this.width 等于 window.width 等于 变量width,所以输出200.

call和apply方法

  • call和apply作用都是改变this
  • call和appy方法区别在于他们的传参的形式不同:
    call(对象,参数1,参数2,…参数n)
    apply(对象,[参数1,参数2,…参数n])

先来个案例:

	var width = 200

	Object.prototype.color = 'red'
	Object.prototype.findWidth = function(){
		console.log(this.width)
	}

	function Person(){
		this.sayWidth = function(){
			console.log(this.width)
		}
		this.getWidth = function(){
			this.findWidth()
		}
		this.callWidth = function(){
			this.findWidth.call(window)
		}
		this.applyWidth = function(){
			this.findWidth.apply(window)
		}

	} 

	var per = new Person()
	per.sayWidth() //undeinfed
	per.getWidth() //undeinfed
	per.callWidth() //200
	per.applyWidth() //200

控制台打印结果:
在这里插入图片描述
分析: per.sayWidth() ,per.getWidth() 这两个函数输出结果为什么undefined,由上述过程分析可知,因为per对象和其原型链中均无width属性,所以输出undefined.
per.callWidth(),per.applyWidth() 方法中分别调用了call和apply方法,传入的参数是window,此时等于this变成了window对象,所以在findWidth()方法中,的this.width等于是widonw.width即为200.

call和apply中传递参数

使用案例:

	Object.prototype.findWidth = function(width,height,color,age){
		this.width = width
		this.height = height	
		this.color = color		
		this.age = age		
	}

	function Person(){
		this.callWidth = function(width,height){
			this.findWidth.call(window,width,height)
		}
		this.applyWidth = function(color,age){
			this.findWidth.apply(window,['','',color,age])
		}

	} 
	var pOne = new Person()
	var pTwo = new Person()
	pOne.callWidth(200,180) 
	console.log(width) //200
	console.log(height) //180

	pTwo.applyWidth("red",18) 
	console.log(color) //red
	console.log(age) //18

在这里插入图片描述
分析:通过call和apply的方法把this变成window,然后按照规则传入参数,即实现了相当于在全局定义变量的功能。


http://www.niftyadmin.cn/n/3654628.html

相关文章

Lua入门系列----pil学习笔记之Getting Start

本文作者:sodme本文出处:http://blog.csdn.net/sodme声明: 本文可以不经作者同意, 任意复制, 转载, 但任何对本文的引用都请保留文章开始前三行的作者, 出处以及声明信息. 谢谢.很多高深的人物都说过类似的话:"语言层面的东西, 都是表面的东西, 最核心的是设计模式, 是算法…

js中hasOwnProperty和instanceof的使用

hasOwnProperty hasOwnProperty方法是用来判断某个属性是否是属于自身对象的,该方法仅用于判断自身对象,不会查找原型链。 案例如下: Person.prototype.name 原型 Person.prototype.myFc function(){}function Person(){this.age 18this.…

Lua入门系列----pil学习笔记之 Type and Values (1)

本文作者:sodme本文出处:http://blog.csdn.net/sodme声明: 本文可以不经作者同意, 任意复制, 转载, 但任何对本文的引用都请保留文章开始前三行的作者, 出处以及声明信息. 谢谢.参考资源:http://www.lua.org/pil/ 一 个小小的脚本语言都能玩出这么多花样来&#xff…

js函数中的形参,实参和arguments对象

形参:形式参数,是函数作用域内的变量。 实参:调用函数时,传入的参数,有对应的形参时,实参会赋值给形参。 案例: var MyF function(a){} //a为形参MyF(1) //1为实参在javascript中的函数中&…

对标号地址的另一种相对寻址方式

汇编程序中, 对数据访问时, 通常是这样的:_asm{...DATA_LABLE:_emit 0x87_emit 0xa0_emit 0x49_emit 0x90...mov ebx, dword ptr [DATA_LABLE]...}其中, 当程序编译之后, mov指令中的DATA_LABLE标号地址会被转成一个绝对地址. 而有时绝对地址这一点可能会对这样一种需求带来障碍…

callee和caller的使用

callee callee是arguments对象中的一个方法,功能是引用arguments所在的函数。 案例: //命名函数 function fn(){console.log(arguments.callee)} fn() 结果如下: //ƒ fn(){console.log(arguments.callee)}//匿名函数 (function(){console.l…

高性能网络编程MailList 热点回顾 [1]

早在今年2月份, 鉴于国内服务器程序开发的同仁一直以来都没有一个固定的场所可以互相交流, 我在google group上建了一个有关高性能网络编程的maillist (加入的方法见这里), 现已经加入的600多名成员中, 所属领域较为广泛: 有从事网游服务器开发的, 有从事IM服务器开发的, 也有…

ES3常用数组方法

增删系列方法: push(元素1,元素2,…,元素n) 功能:往源数组的末端添加元素。 返回值:添加元素后,源数组的长度。 示例: var a [1] a.push(2,3,4) console.log(a) //(4) [1, 2, 3, …