Context and scope

A new declaration ways, new ways to bring the declaration what? Block-level scope
before let, js only global scope and function scope, it first on a chestnut

if(false){
   var aa = 111;
}
console.log(aa) // 111

for(var i=0;i<5;i++){
   var bb = 222;
}
console.log(i) //5
console.log(bb)  //222

In fact, if the word begins to brace the end, for the word from the beginning to the end there is scope braces, called block-level scope == block-level scope with logical judgment jump, return can not jump out of block-level scope, == function scope can only jump, he can be external access because var variables and functions to enhance the lift, get rid of a habit, do not declare the function on if and for years, there is only variable improved, if the the above code changed to let, let const with the same, because no one will speak when const variables

if(false){
   let aa = 111;
}
console.log(aa) // 错误

for(let i=0;i<5;i++){
   let bb = 222;
}
console.log(i) //错误
console.log(bb)  //错误

let let the above aa, i, bb domain use only a small role in that, if the same functions have the same scope or global scope variables will be a lot safer if that does not make sense, then it is followed by var, no difference

let / const with var What is the difference

// 面试题来着
// 这里是全局作用域window
var aa = "aa"
let bb = "bb"
console.log(window.aa)  //"aa"
console.log(window.bb)  //undefined
console.log(window.cc)  //undefined
console.log(aa)  //"aa"
console.log(bb) //"bb"
// bb并不在window里,因为他在自己的作用域里,只能用变量名去取值

Therefore, the scope of known global scope, function scope, block-level scope, is simulated by the code

// 当页面被打开,就有一个全局作用域window
window = {
  // 还有页面里所有的dom和bom
  var dom = {}
  var bom = {}

  // 下面的内容就是程序员自己的代码或者插件了
  var name = "tom"
  function aa(){
    // 函数作用域
    if(true){
      // 块级作用域
      let name = "jee"
    }
    console.log(name) //"tom"
  }
}

The context of the
review of the scope of a function hidden something
there hidden argumentsparameters pseudo-arrays, and if dom time, there is eventan event object, and there is certainly some thiscontext == function is executed there must be a performer, this is the executor of the function ==

// 这个都理解不了就转行吧
var name = "我是window"
function init(){
   console.log(this)  // window
   console.log(this.name)  // "我是window"
}
init()  //实际是window.init()
// 这个都理解不了就转行吧
var obj = {
   name: "我是obj",
   init(){
      console.log(this)  // obj
      console.log(this.name)  // "我是obj"
   }
}
obj.init()

If I do not want to write init obj, because I have to use window repeatedly write very well how to do
with the function of the method apply, call, bind
the three brothers is a classic interview

var name = "我是window"
var obj = {
   name: "我是obj",
}
// 加两个
function init(x,y){
   console.log(x,y)
   console.log(this)
   console.log(this.name)
}
// 直接执行init肯定就是window了
init(1,2)
// 修改this方式一,立即执行
init.call(obj,1,2)
// 修改this方式二,立即执行
init.apply(obj,[1,2])
// 修改this方式三,不立即执行,后续执行
init.bind(obj)(1,2)

He said apply
as apply parameters can be turned into an array, so this powerful advantage to let people forget that he actually used to change this in

Math.max.apply(null, [14, 3, 77]) //第一个参数是空因为Math本来就是window的子对象
arr1.push.apply(arr1,arr2) //第一个参数需要是this自己,用null就没了
// 还可以这么写
Array.prototype.push.apply(arr1, arr2);
... 
//一切可以无限传参数的方法都可以用apply改成传数组

Apply, however instead be extended operator

Math.max(...[14, 3, 77])
arr1.push(...arr2);
arr1.push(...arguments);

Retains the this
== function is executed in a function definitely window ==

function init(){
   console.log(this)
}
document.querySelector("#id").onclick = function(){
   console.log(this) //dom#id....
   console.log(this.style.color)
   init() // 我们总是以为这个是当前this执行的,但实际是window执行的
}

In order for init to get this in front of a function, the most common practice is to var that = this
then put that as a parameter passed in the past, this is no problem, but it is difficult to maintain, it is vomiting blood, a lot of judgment

function cb(that){
   console.log(that)
}
var obj = {
   name: "我是obj",
   init(cb){
      console.log(this)
      var that = this; 
      cb(that)
   }
}
obj.init(cb)

The above call, apply, bind directly modify the context this, rather than as a context parameter to pass

function cb(that){
   console.log(that)
}
var obj = {
   name: "我是obj",
   init(cb){
      console.log(this)
      cb.call(this)
   }
}
obj.init(cb)

Arrow function can save this, but must be declared within the parent function

var obj = {
   name: "我是obj",
   init(){
      console.log(this)
      // 箭头函数执行是往上找执行者,直到找到一个执行者后停下来
      // 如果如果上一级也是箭头函数就继续往上找
      // 箭头函数没有三个改变this的方法
      // 一般也不会在这里声明一个cb函数,cb函数一般都是作为参数传进来的
      var cb = () => { console.log(this) };
      cb()  // obj 
   }
}
obj.init()

Arrow timer function in the most obvious effect

var name = "name1";
function init(){
   var name = "name2";
   // 这个改的是window的name
   setTimeout(function(){
      this.name = "new"
   },2000)
   // 这个改的是上面的name
   setTimeout(()=>{
      this.name = "new"
   },2000)
}

== this use is very small, it will not often need to modify this, use custom plug on a lot of ==

Go to work after learning java own functions AOP-oriented development of a js

function aop(funArr,beforeFun,afterFun,context){
    var thatContext = context;
    var that = this;
    this.init = function(){
        that.funArrEach(funArr,thatContext);
        return that;
    }
    this.funArrEach = function(arr,context){
        arr.forEach(function(fun){
            that.addAop(fun,context)
        })
    }
    this.addAop = function(fun,context){
        var context = context || window;
        context[fun.name] = function(){
           beforeFun()
           fun.call(context,...arguments)
           afterFun()
        }
    }
    this.push = function(opt,context){
        var context = context || thatContext;
        if(Object.prototype.toString.call(opt)=="[object Array]"){
            that.funArrEach(opt,context);
        }
        if(Object.prototype.toString.call(opt)=="[object Function]"){
            that.addAop(opt,context);
        }
    }
}

function aopBeforeFun() { ... }

function aopAfterFun() { ... }

new aop([a,b,c],aopBeforeFun,aopAfterFun).init()

Improved version, sometimes aopBefore need to determine whether to perform

this.addAop = function(fun,context){
    var context = context || window;
    context[fun.name] = function(){
       if(beforeFun(fun,context,arguments)){

       }else{
          fun.call(context,...arguments)
       }
       afterFun()
    }
}
function aopBeforeFun(cb,context,arg) {
    if(true){
      // 自己执行
      cb.call(context,...arg)
      return true;
    }else{
      // 跳过不执行了
      return true
    }    
}

aopAfter can be so changed by the above

Guess you like

Origin www.cnblogs.com/pengdt/p/12037964.html