26-知识整理1

26 阅读3分钟

知识体系 就是区分 干活的人 和 创造价值的人的开始

程序是怎么执行的?

  1. 先进行分词(词法分析) CString str = "hello" CString / str / = / "hello"/

  2. 构建AST(抽象语法树)

  • 通过一个json去描述 每一个词是干什么的
  1. 代码生成

(JIT) JS执行主要分为2个阶段:

  • 代码的预编译阶段
    • 前置阶段:
      • 1.变量声明
      • 2.变量提升,但值为undefined
      • 3.非表达式函数进行提升
  • 代码执行阶段
console.log(a);//undefined
var a = 10;

// => 等效
var a;
console.log(a);
a = 10;

一个变量如何被赋值和使用的,有什么区别?

var a = 2;
 
1. var a
- 编辑器会先问作用域,是不是已经有了一个a,在当前作用域中了?
    + 是:忽略这个声明,继续往下走
    + 否: 在当前作用域中,生成一个新变量,并命名为 a
2. a = 2
- 编译器会去找是否当前作用域已有a?
    + 是: 赋值为2
    + 否: **回去上一层作用域去找**
var a = 10;
function foo() {
    a = 2;
    console.log(a);// 2
}
foo();
console.log(a)//2

作用域

  • 就是更具名称查找变量的规则

词法作用域(静态作用域)

  • 定义在词法阶段作用域(代码写在哪里作用域就在哪里),因此词法分析器处理代码时,会保持代码不变(eval,with除外,不推荐使用)

函数作用域

  • 属于函数的全部变量,都可以在整个函数范围使用

上下文

  • 词法作用域是在写代码的时候,或者在定义的时候确定的
  • 动态作用域(js没有真正的动态作用域),是在运行时确定的
  • [高阶函数]

例子1

foo(10);
function foo(num) {
    var foo;
    console.log(foo);//undefined
    foo = num;
    console.log(foo);//10
}

console.log(foo);//function
foo = 1;
console.log(foo);//1

this

闭包

  • 闭包是一种显现,函数嵌套函数时,内存函数引用了外层函数作用域的变量,并且内层函数在全局作用域下能访问
// => eg1
function fun() {
    let num = 1;
    return () => {//词法作用域
        console.log(num);
    }
}

var x = fun();
x();
x();

// => eg2
const foo = (function() {
    var v = 0;
    return () => v++;
})();

for(let i = 0; i < 10; i++) {
    foo();
}
console.log(foo());//10

// => eg3
var fn1;

const fuc = function() {
    var a = 2;
    function inner() {
        console.log(a);
    }

    fn1 = inner;
}
func();

function bar() {
    fn1();
}

bar();//2

this

this指向什么?

this 的指向,是根据上下文,动态决定的

  • 在简单调用时, this 默认指向 window/global/undefined (浏览器/node/严格模式)
  • 对象调用时,绑定在对象上;
  • 使用 call、apply、bind时,绑定在指定的参数上
  • 使用 new 关键字,绑定到新建的对象上 (以上优先级 new > apply/call/bind > 对象调用)
  • 使用箭头函数,根据外层的规则决定

例子1

const foo = {
    bar: 10,
    fn: function() {
        console.log(this);
        console.log(this.bar)
    }
}

var fn1 = foo.fn;
fn1();
// this => window  this.bar => undefined 浏览器中
// this => global  this.bar => undefined node中

foo.fn();// this ->  foo  this.bar -> 10

例子2

const s = {
    name: 'Luck',
    fn: function() {
        return this;// s
    }
}
console.log(s.fn() === s);//true

例子3

const p = {
    name: 'lucy',
    brother: {
        name: 'rr',
        fn: function() {
            return this.name;
        }
    }
}
console.log(p.brother.fn());
//this -> p.brother -> rr

例子四

const o1 = {
    text: 'o1',
    fn: function() {
        return this.text
    }
}

const o2 = {
    text: 'o2',
    fn: function() {
        return o1.fn();
    }
}

const o3 = {
    text: 'o3',
    fn: function() {
        var fn = o1.fn;
        return fn();
    }
}

console.log(o1.fn());// o1
console.log(o2.fn());// o1
console.log(o3.fn());// undefined

例子5

const foo = {
    name: "lucy",
    logName: function() {
        console.log(this.name);
    }
}

const bar = {
    name: 'mike'
}

console.log(foo.logName.call(bar));// mike

例子6

var num = 3;

var obj = {
    num: 3,
    fn: (function() {
        var num;
        this.num += 2;//10 window
        num = 3;
        return function() {
            var n = this.num;//10  3 
            this.num *= 2;// 20  6 
            console.log(n);//3  3
            num *= 3;// 9
            console.log(num);//9
        }
    })()
}
var fn = obj.fn;
fn.call(null);// 10 9
obj.fn();//3  27
console.log(window.number);//20