谈下自己对this,call,apply的理解

工作中经常被this坑,虽然解决了但一直没有去整理,现在集中整理下自己对this的理解,也是百度了很久,看了很多大神的写的,都很详细,自己整理一下,加深对this的印象吧。
之前看到一句话this用通俗一点的话来讲就是谁调用它,它就指向谁,说的好像没毛病。
但是还是要分细一点:this的指向
在没有任何任何操作下,this是指向全局的即window。
1:在作为对象的方法被调用时:this指向该对象

 window.name = "cheng000";
    var obj = {
    				name:"cheng",
    				getname:function () {
    					console.log(this.name)
    				}
    			};
    			obj.getname();//cheng

2:作为普通函数调用:this是指向全局的即window;

var getName0 = obj.getname;
getName0();//"cheng000"
这个例子可以和document.getElementById结合着想
var el=document.getElementById(‘div’)和var getId = document.getElementById;getId (‘div’)是不一样的,前者函数内部的this指向是document,后者是指向window
或者:
var getName = function () {
	var name = "cheng1";
	return this.name;
}
console.log(getName()) // chengcan000不是cheng
或者:
obj.getname1 = function(){
    function newgetname () {
		console.log(this.name)
	}
	newgetname()
}
obj.getname1()

所以不管this在哪里,只要是作为普通函数或者独立函数来调用,就是指向window,

3:构造器的使用:构造函数 this就是指向返回的这个的对象

var person = function(){
	this.name="ch";
	this.getName=function () {
		return this.name;
	}
}
var person1 = new person();
console.log(person1.getName())//ch

4:结合Function.prototype.call或者是apply调用可以改变this指向

var obj2 = {
 	name:"cheng2",
 }
 obj.getname.call(obj2)

这里用到了call,call和apply是给function定义的两个方法:Function.prototype.call和apply,call和apply基本上是一样的,它们的第一个参数是指定了体内this的指向,call后面的参数是传的动态的参数,apply就只有一个参数,这个参数就是所有动态的参数集合的一个数组;
上述的第四种用法就是call和apply的用途之一,
还有就是继承,就用apply做例子吧

function dd (name,age,sex) {
	this.name=name;
	this.age=age;
	this.sex=sex;
	this.showsex=function  () {
		console.log(this.sex)
	};
	this.showage=function () {
		console.log(this.age)
	};
	
};
dd.prototype.showage1 = function () {
			console.log(this.age)
		}
function cc (name1,arry) {
	this.name1 = name1;
	this.showname=function () {
		console.log(this.name+"今年"+this.age+"性别:"+this.sex+this.name1)
	};
	dd.apply(this,arry)//call前面为父级,括号里面为子元素;子能获取父元素的内容,父级不能用子,这里的参数arry是cc这个构造函数的参数传过来的,我看的时候完全晕在这里了,还好我足够努力。
};
var me=new cc('xiaobai',['xiaohong',18,'men']);
me.showname();、//xiaohong今年18性别:menxiaobai  cc能用bb里面的方法
me.showsex(); //men
me.showage(); //18
 me.showage1(); //继承只能继承实例,而不能继承原型

说道apply,有一个很有用的方法两个数组的叠加,当然你用concat()也可以,但是会增加一个新的数组,

var new1arr = [1];
var new2arr = [2,3];
console.log(new1arr.concat(new2arr))
Array.prototype.push.apply(new1arr,new2arr);
console.log(new1arr)//[1,2,3]
还有一种
for(var i in new2arr){
    new1arr.push(new2arr[i]);
}

但是看上去比较麻烦,对于程序员还是越少代码越好,是吧,既然说到了原型就说下吧
原型:在js中每当定义一个函数数据类型(普通函数,类)时候,都会自带一个prototype属性,这个属性指向原型对象,原型对象是共有的,每一个实例都能够访问

function Person(name) {
				this.name = name;
			}
			Person.prototype.getName = function () {
				console.log(this.name)
			}
			var person1 = new Person('xiaohong');
			person1.getName()
			console.log(Person.prototype==person1.__proto__)//true
			console.log(Person.prototype.constructor==Person)//true

原型链:每一个数据类型(普通的对象,实例,prototype)都有__proto__,数据类型(实例)的—__proto__的指向Person的prototype。constructor是prototype的一个属性,他又指回函数。每当你new一个对象的时候,实际上经历了person1-Person-Object这样的就会形成链。可以看出Object是原型链的顶端,任何对象的原型链最终都会指向Object的原型。在网上找到一张图,很清楚的带你了解原型链
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值