关于this

98 阅读3分钟

this的作用

this的作用可以放我们在函数中的对象快速的调用到函数中的各种变量 如果没有的话当函数改名的时候 对乡里对应的数据也要随之改名

this在全局作用域指向什么

  • 在浏览器中 this一般指向的就是 windows 也就是GO 全局对象

  • 但是在node里面 this一般指向的是一个空对象 流程如下👇

    module ==> 加载 编译 放到一个函数中 执行 Fn.apply({}) 然后就会使这个this指向一个空对象

关于this的指向

  • 函数在调用的时候 会产生一个函数执行上下文 函数执行上下文里就有一个this 这个时候js会给this绑定一个值
  • this的绑定和编写的位置没有关系
  • this的绑定和调用方式以及调用的位置有关系
  • this是在运行的时候被绑定的

this的绑定规则

四种方式:默认绑定 隐式绑定 显示绑定 new绑定

  • 在默认绑定中 只要是独立函数调用 那么this指向的就是window
function foo() {
	function bar() {
       console.log(this)
   }
   return bar
}

const fn = foo()
fn()		//此时输出的还是window 因为这个独立函数调用

const obj = {
   name: "whiy",
   eating: fn
}

obj.eating()		//此时输出的就是一个对象obj了
  • 隐式绑定
function foo() {
   console.log(this)
}

const obj = {
   name = "why",
   foo: foo
}
obj.foo()		//此时输出的this就是obj对象了
  • 其实隐式绑定就是这样调用函数 ==> obj.fn()
  • obj对象会被js引擎绑定到fn函数中的this里面
  • 隐式绑定有一个前提脚尖就是调用的对象内部要有一个对函数的引用(比如一个属性),没有这样引用的话 再进行调用的时候会报错 找不到这个函数,正是这个引用将this绑定到这个对象上面了
  • 直接调用 || apply() || call()
const obj = {
   name: "duixiang"
}
foo()

foo.apply(obj)
foo.call(obj)

直接调用foo函数的话 foo中的this指向的是window

但是如果使用apply或者call来调用的话 可以使其绑定上一个函数

  • call 和 apply 的区别
function sum(num1, num2) {
   console.log(num1 + num2, this)
}
sum.call("call", 20, 30)
sum.apply("apply", [20, 30])

区别就是在传参数的时候 apply使用数组 call是一个一个穿的

  • 显示绑定
function foo() {
   console.log(this)
}
const newFoo = foo.bind("aaaa")

nrwFoo()	//这个时候由于显式绑定了 所以指向的就是foo对象

// 关于优先级 显式绑定 > 默认绑定

题外话

就是说今天才知道了一个东西 就是V8引擎在实现的时候 很多东西做了优化 今天知道的就是 在分配空间的过成功 正常来说一个字符 number 占据的是8bytes 也就是8个字节 但是v8引擎为了实现空间的优化 只会分配给其4个字节 原本可以表示数字的范围是2^64次方 现在可以表示的是2^32次方 (-2^32 + 1  ==>  2^31 - 1)

youxianji

image.png

image.png

image.png

image.png

image.png

image.png

image.png

箭头函数 arrow function

  • 箭头函数是ES6之后增加的编写函数的方法 比函数表达式更加简洁
    • 箭头函数不会绑定this arguments属性
    • 箭头函数不能作为构造函数来使用

image.png

image.png

image.png

箭头函数的编写优化

  • 优化一:如果只有一个参数()可以省略
nums.forEach(item => {})
  • 优化二:如果函数执行体中只有一行代码 那么可以省略大括号
    • 并且这行代码的返回值会作为整个函数的返回值
nums.forEach(item => console.log(item))
nums.filter(item => true)
  • 优化三:如果函数执行体只有一个返回对象 那么需要给这个对象加上()
var foo = () => {
    return { name: "abc" }
}
var bar = () => {(name: "abc")}

面试题一

var name = "window" //是window.name = "window"
var person = {
    name:"person",
    sayName: function() {
        console.log(this.name)
    }
};
​
function sayName() {
    var sss = person.sayName;
    sss();  //window
    person.sayName();   //person 隐式调用
    (person.sayName)(); //person 隐式调用
    (b = person.sayName())();   //window 赋值表达式 独立函数调用
}
​
sayName();

面试题二

\