zoukankan      html  css  js  c++  java
  • JavaScript的this

    this

    首先,说下this的两个常见误区

    指向自身?

    因为this的从英文的角度上,很容易给人自身感觉,导致出this指向函数自身的想法。

    function foo(){
    	var a = 4;
    	console.log(this.a); // undefined
    	console.log(this.b); // undefined
    	console.log(foo.b);; // 1
    }
    
    foo.b = 1;
    foo()
    

    很明显,this并不是指向函数自身的,this.bfoo.b并不是同一个

    this指向与函数的作用域有关?

    function foo(){
    	var a = 4;
    
    	function baz(){
    		console.log(a); // 4
    		console.log(this.a); // undefined
    	}
    
    	baz()
    }
    
    foo()
    

    试图用作用域链的方法查找a,然而this并不买账。

    那么接下来开始真正介绍this

    this的绑定规则

    this的绑定要判断用了什么规则,总共有四条。

    默认绑定

    默认绑定就是this指向window

    var a = 4;
    
    function foo(){
    	this.bar();
    }
    
    function bar() {
    	console.log(this.a) // 4
    	console.log(window.a) // 4
    }
    
    foo()
    

    正是因为this指向window,而bar和a又刚好作为window的属性,所以可以访问

    当其他规则无法适用时,就会绑定到window

    隐式绑定

    如果函数作为某个对象的属性,那么this就会指向这个对象

    var a = 4;
    
    function foo(){
    	this.bar(); // 2
    	console.log(this.a); // 1
    }
    
    var obj = {
    	a: 1,
    	bar: function(){
    		console.log(2)
    	},
    	foo
    }
    
    obj.foo()
    

    从这也可以看出,隐式绑定的优先级要高于默认绑定

    丢失绑定

    隐式绑定如果操作不当,会导致绑定丢失

    var a = 4;
    
    function foo(){
    	//this.bar(); 报错,this指向window,但window没有bar函数
    	console.log(this.a); // 4
    }
    
    var obj = {
    	a: 1,
    	bar: function(){
    		console.log(2)
    	},
    	foo
    }
    
    var baz = obj.foo;
    baz()
    

    这种情况下,将对象里的函数赋值给一个变量baz,所以baz是foo的引用,但是它引用的是foo本身,并不是obj里的foo,所以这时候的this就指向了window

    显示绑定

    通过call()apply()来改变this的指向

    var a = 4;
    
    function foo(){
    	console.log(this.a); // 1
    }
    
    var obj = {
    	a: 1
    }
    
    var obj1 = {
    	a: 2
    }
    
    function baz() {
    	foo.call(obj1); // 2
    }
    
    function bar(){
    	foo.call(obj)
    }
    bar(); // 1
    baz()
    foo(); // 4
    
    
    

    foo.call(this要绑定到的对象),通过this.call就可以指定this的对象了,不过这里要注意的是,并不是绑定后,foo的this就到指定的对象了,只有在执行这段代码foo.call()的时候,this才发生改变,最后一行代码,单独调用了foo,this依然指向window。

    new绑定

    使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作

    • 创建一个全新的对象
    • 这个新对象会被执行[[Prototype]]连接
    • 这个新对象会绑定到函数调用的this
    • 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象
    function foo(a){
    	this.a  = a;
    	
    	this.baz = function(){
    		console.log('hellow'+ a)
    	}
    }
    var bar = new foo(2);
    console.log(bar.a)
    bar.baz();
    

    这时this就指向了new出来的实例了

  • 相关阅读:
    简单方法实现无刷新提交Form表单
    [LeetCode] 654. Maximum Binary Tree
    [LeetCode]3. Longest Substring Without Repeating Characters
    《设计模式之禅》读书笔记(四)之抽象工厂模式
    《设计模式之禅》读书笔记(三)之扩展工厂方法模式
    《设计模式之禅》读书笔记(二)之工厂方法模式
    《将博客搬至CSDN》
    php解析excel文件
    git 删除分支
    git 修改注释信息
  • 原文地址:https://www.cnblogs.com/tourey-fatty/p/12119952.html
Copyright © 2011-2022 走看看