scope
A scope is the scope within which a variable is legally used. It can be divided into:
- Global scope
- Function scope
- Block-level scope
Variable ascension
Before a JS script (a
Function declarations take precedence over variable declarations.
Free variables
- A variable is not defined in the current scope, but is used
- They’ll go up to the top until they find it
- If the global scope is not found, XXX is not defined
These layers of relationships are called scope chains.
All free variables should be found in the function definition, in the parent scope, not in the execution place.
this
this
It’s who executes you
This is part of the execution context, and the value of this is determined at function execution time, not function definition time.
var cyName = 'window-cy'
var obj = {
cyName: 'obj-cy',
printName: function(from){
console.log(from + ': ' + this.cyName)
}
}
obj.printName('obj') // obj-cy
obj.printName.call({cyName: 'call-cy'},'call') // call-cy
var p = obj.printName
p('window') // window-cy
Copy the code
Var cyName = ‘window-cy’ if let cyName = ‘window-cy’, p(‘window’) will print undefined. Since p(‘window’) this is window, var declarations are automatically mounted to window, but let is not.
this
Usage scenarios of
- Execute as a normal function
- Execute as an object property
- Execute as a constructor
- Arrow function
- use
call
apply
bind
call
closure
Closures are functions that refer to variables in the scope of another function.
Closure usage scenarios
- Function is returned as the return value
- Functions are passed as arguments
function F1() {
var a = 100
return function () {
console.log(a) // 100
}
}
var f1 = F1()
var a = 200
f1()
Copy the code
function F1() { var a = 100 return function () { console.log(a) // 100 } } function F2(f1) { var a = 200 f1() } var f1 = F1() F2(f1)Copy the code
Application scenarios for closures in real development
- Hide data and only provide apis to the outside world
- Implement debounce and throttle control
function createCache(){
const prefix = 'portal-'
const data = {}
return {
set: function(key,value){
data[prefix + key] = value
},
get: function(key){
return data[prefix + key]
}
}
}
const c = createCache()
c.set('name','cy')
cy.get('name')
Copy the code
Related topics
var a = 10; function b() { a = 100; } b(); console.log(a); / / 100Copy the code
Var a = 10; function b() { a = 100; return; Function a() {} function a() {} function a() {} function b (funciton a); The next modification is the local variable A of function B, independent of a in the outer scope. } b(); console.log(a); / / 10Copy the code
var a = 10; if(true) { var a = 100; // var declares variables without block-level scope} console.log(a); / / 100Copy the code
var name = 'map'; function func() { console.log(this.name); // map } var object = { name: 'object', getNameFunc: function(fn) { fn && fn(); Return () => {return this.name; } // Arrow function this refers to the parent scope, so this is object}}; console.log(object.getNameFunc(func)()); // object // Result output // map // objectCopy the code
handwrittencall
apply
bind
function
Feature implementations that use functions called as object properties
var cyName = 'window-cy' var obj = { cyName: 'obj-cy', printName: function (from) { console.log(from + ': ' + this.cyName) } } obj.printName.call({ cyName: 'call - cy'}, 'call'). The Function prototype. CyCall = Function (o) {const symbol = symbol () o (symbol) = this / / who call cyCall, Who is this / / to take the first parameters outside the let the args = Array. The prototype. Slice. The call (1) the arguments, / / arguments is an Array (containing the length attribute object), Typeof arguments is object. Array. The prototype. Slice. The call can put the class into an Array Array (symbol) (o... args) delete o[symbol] } obj.printName.cyCall({ cyName: 'cyCall-cy' }, 'cyCall') Function.prototype.cyApply = function (o) { const symbol = Symbol() o[symbol] = this const args = Array.prototype.slice.call(arguments, 1) o[symbol](... args.flat()) delete o[symbol] } obj.printName.cyApply({ cyName: 'cyApply-cy' }, ['cyApply']) Function.prototype.cyBind = function (o, ... args) { return (... innerArgs) => { const symbol = Symbol() o[symbol] = this o[symbol](... args, ... innerArgs) delete o[symbol] } } obj.printName.cyBind({ cyName: 'cyBind-cy' }, 'cyBind')()Copy the code