# this

this问题千花百样,面试总问,那我们就不厌其烦的看,看到吐为止 再次加强对this谁调动指向谁的问题

this.a = 20;
var p = {
    a:30,
    test:function() {
        alert(this.a)
    }
}
p.test()//30 this->p
var s = p.test
s();// 20 thos->window

this.a = 20;
var test = {
    a: 40,
    init: () => {
        console.log(this.a);
        function go() {
            this.a = 60;
            console.log(this.a)
        }
        go.prototype.a = 50;
        return go;
    }
};
var p = test.init()
p()
new (test.init())();
20 60 60 60

# 原型

    var Car = function (color) {
        //constructor == Car 构造函数和初始化这个类是一个东西
        this.color = color;
        console.log(111);
    }

    Car.prototype.sell = function () {
        console.log(this.color + "色的车被卖了");
    }

    var BWM = function (color) {
        Car.call(this, color)
    }

    BWM.prototype = new Car() //111
    var m = new BWM('red') //111
    console.log(m)

avatar

需要解决问题

  • 1、拿到父类原型链上的方法

  • 2、不能让构造函数执行两次

  • 3、引用的原型链不能是按址引用

  • 4、修正子类的constructor

    var Car = function (color) { //constructor == Car 构造函数和初始化这个类是一个东西 this.color = color; console.log(111); }

    Car.prototype.sell = function () { console.log(this.color + "色的车被卖了"); }

    var BWM = function (color) { Car.call(this, color) }

    var __pro = Object.create(Car.prototype); __pro.constructor = BWM; BWM.prototype = __pro; var m = new BWM('red') //111 console.log(m)

avatar

# 套路题

(function () {
    var a = 200;
    var b = c = a;
})()
alert(c)

(function () {
    var a = 200;
    var b ,c = a;
})()
alert(c)

# bind

var user = {
    age:20,
    init:function() {
        console.log(this.age)
    }
}

var newUser = {age:28};
user.init.bind(newUser)//空 返回的是一个新函数
user.init.bind(newUser)()//28
var newBind = user.init.bind(newUser)
newBind()//28

# 总结

1、立即执行函数

2、闭包 当内部函数被保存到外部的时候就会产生闭包,闭包会导致原有的作用域链不被释放,产生内存泄漏

//实现公有变量 闭包实现一个累加器
function add() {
    var count = 0;
    function demo() {
        count++;
        console.log(count);
    }
    return demo
}

var counter = add();
counter();
counter();
1
2
3
4
5
6
7
8
9
10
11
12
13
//可以做缓存(保存数据结构)
function test() {
    var num = 100;
    function a() {
        num++;
        console.log(num);
    }
    function b() {
        num--;
        console.log(num);
    }
    return [a,b]
}
var myArr = test()
myArr[0]()
myArr[1]()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    //可实现封装,属性私有化
function Deng(name, wife) {
    var prepareWife = 'xiaozhang' //变量变成了自己私有化的变量,别人无法访问
    this.name = name
    this.wife = wife
    this.divorce = function () {
        this.wife = prepareWife
    }
    this.changePrepareWife = function (target) {
        prepareWife = target
    }
    this.sayPrepareWife = function () {
        console.log(prepareWife)
    }
}

var deng = new Deng('deng', 'xiaoliu')
deng.divorce()
console.log(deng.wife) //xiaozhang
deng.sayPrepareWife() //xiaozhang
console.log(prepareWife) //prepareWife is not defined
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//模块开发,防止污染全局变量
var name = 'xiaozhang';
var init = (function () {
    var name = 'xiaoming';
    function callName() {
        console.log(name)
    }
    return function () {
        callName()
    }
}())

init()//xiaoming
1
2
3
4
5
6
7
8
9
10
11
12
13

3、原型链 3.1 构造函数理的属性的优先级比原型链的要高 3.2 面向对象编程的时候JS没有类的概念 可以用函数代替 3.3 constructor 实际就是对应的那个函数 3.4 prototype 按引用传递的 object.create创建原型的副本

4、数值 字符串 布尔类型 按值传递 对象数组按引用传递

5、改变this执行 bind call apply

6、预编译 1、创建AO对象 (执行期上下文) 2、找形参和变量声明(变量提升),将变量和形参最为AO属性名,值为undefined 3、将实参值和形参统一 4、在函数体里面找函数声明,值赋予函数