The this point in the JS function (below)

1. This binding of built-in functions (this analysis of some functions)

1.1 setTimeout (independent function call)

setTimeout(function () {
    
    
  console.log(this); // window
}, 2000);

1.2 Listening for clicks (implicit binding)

<body>
    <div class="box"></div>
</body>    

//监听点击
const boxDiv = document.querySelector(".box");
boxDiv.onclick = function () {
    
    
  console.log(this);   //<div class="box"></div>
};

boxDiv.addEventListener("click", function () {
    
    
  console.log(this);    //<div class="box"></div>
});

1.3 array forEach (if not bound, the default window)

// 数组.forEach/map/filter/find
var names = ["abc", "cba", "nba"];
names.forEach(function (item) {
    
    
  console.log(item, this);
}, "abc");
//abc String {'abc'}
//cba String {'abc'}
//nba String {'abc'}

names.map(function (item) {
    
    
  console.log(item, this);
}, "cba");

//abc String {'cba'}
//cba String {'cba'}
//nba String {'cba'}

2. Rule priority

①Default binding has the lowest priority
②call/apply explicit binding is higher than implicit binding
③bind has higher priority than implicit binding
④new has higher priority than implicit binding and higher than bind

default binding (independent function call) < implicit binding (obj.foo()) < explicit binding (apply/call/bind) < new binding

Note:
New binding, call, and apply are not allowed to be used at the same time, so there is no one with higher priority.
New binding can be used together with bind, and new binding has a higher priority.

//bind的优先级高于隐式绑定
function foo() {
    
    
  console.log(this);
}

var obj = {
    
    
  name: "obj",
  foo: foo.bind("aaa"),
};

obj.foo(); //String {'aaa'}
var obj = {
    
    
  name: "obj",
  foo: function () {
    
    
    console.log(this);
  },
};

// new的优先级高于隐式绑定
var f = new obj.foo(); //foo {}
// new的优先级高于bind
function foo() {
    
    
  console.log(this);
}

var bar = foo.bind("aaa");

var obj = new bar(); //foo {}

3. Outside this rule

3.1 Ignore display bindings:

If we pass in a null or undefined in the display binding, then the display binding
will be ignored and the default binding rules will be used

function foo() {
    
    
  console.log(this);
}
  
foo.apply("abc");    // String {'abc'}
foo.apply({
    
    });      //{}

// apply/call/bind: 当传入null/undefined时, 自动将this绑定成全局对象
foo.apply(null);     //Window
foo.apply(undefined);   //Window

var bar = foo.bind(null);
bar();   //Window

3.2. Indirect function reference:

Creates an indirect reference to a function , in which case the default binding rules are used

var obj1 = {
    
    
  name: "obj1",
  foo: function () {
    
    
    console.log(this);
  },
};

var obj2 = {
    
    
  name: "obj2",
};

obj2.bar = obj1.foo;
obj2.bar();   //obj2对象

(obj2.bar = obj1.foo)(); //Window
//赋值(obj2.foo = obj1.foo)的结果是foo函数
//foo函数被直接调用,那么是默认绑定

3.3, ES6 arrow function

(1)
①The arrow function does not use the four standard rules of this (that is, does not bind this), but determines this according to the upper scope.
② There is no scope when defining an object

Note: Arrow functions will not bind this, and the arguments attribute
cannot be used as a constructor (it cannot be used with new, and an error will be thrown)

(2) The direction of this in the arrow function

var name = "why";

var foo = () => {
    
    
  console.log(this);
};

foo(); //Window
var obj = {
    
     foo: foo };
obj.foo(); //Window
foo.call("abc"); //Window
// 2.应用场景
var obj = {
    
    
  data: [],
  getData: function () {
    
    
     console.log(this);  //obj对象
    // 发送网络请求, 将结果放到上面data属性中
    // 在箭头函数之前的解决方案
    // var _this = this
    // setTimeout(function() {
    
    
    //   var result = ["abc", "cba", "nba"]
    //   _this.data = result
    // }, 2000);
    // 箭头函数之后
    setTimeout(() => {
    
    
      console.log(this);   //obj对象
      var result = ["abc", "cba", "nba"];
      this.data = result;
    }, 2000);
  },
};

obj.getData(); //到上层作用域中,找到getData函数作用域,绑定的是obj对象
//因此这里第15行绑定的也是obj对象

(3) Arrow functions have some common shorthands:

//简写一: 如果参数只有一个, ()可以省略
nums.forEach(item => {
    
    
  console.log(item)
})
// 简写二: 如果函数执行体只有一行代码, 那么{}也可以省略
// 强调: 并且它会默认将这行代码的执行结果作为返回值
nums.forEach(item => console.log(item))
var newNums = nums.filter(item => item % 2 === 0)
console.log(newNums)

// filter/map/reduce
var result = nums.filter(item => item % 2 === 0)
                 .map(item => item * 100)
                 .reduce((preValue, item) => preValue + item)
console.log(result)
// 简写三: 如果一个箭头函数, 只有一行代码, 并且返回一个对象, 这个时候如何编写简写
//在对象外面加上一个小括号()
// var bar = () => {
    
    
//   return { name: "why", age: 18 }
// }

var bar = () => ({
    
     name: "why", age: 18 })

Guess you like

Origin blog.csdn.net/weixin_53737663/article/details/127115672