js相关问题汇总(一)

155 阅读3分钟

1. this

this永远指向最后调用它的对象(setTimeout指向windows)

  var name = "windowsName";

    function fn() {
        var name = 'Cherry';
        innerFunction();
        function innerFunction() {
            console.log(this.name);      // windowsName
        }
    }
    
    fn()

怎么改变this指向?

  • ES6箭头函数
  • 函数内部声明 _this = this
  • 使用 apply、call、bind
  • new实例化对象

箭头函数

箭头函数的this 始终指向函数定义时的this,并非执行时候的

箭头函数中没有this绑定,必须查找作用域链决定值,如果被非箭头函数包含则是最近一层非箭头函数的this,否则是undefined。

函数内部声明 _this = this

简单过了

使用 apply、call、bind

    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    b.apply(a,[1,2])     // 3
    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    b.call(a,1,2)       // 3
    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    b.bind(a,1,2)()           // 3 (手动调用)

js中函数的调用

  • 作为一个函数调用
  • 函数作为方法调用
  • 使用构造函数调用函数
  • 作为函数方法调用函数(call、apply)

2. 原型、原型链

原文链接:www.jianshu.com/p/be7c95714…

prototype

每个函数都有prototype属性,每个js对象(null除外)都会从原型继承属性

    function Person() {
    
    }
    // 虽然写在注释里,但是你要注意:
    // prototype是函数才会有的属性
    Person.prototype.name = 'Kevin';
    var person1 = new Person();
    var person2 = new Person();
    console.log(person1.name) // Kevin
    console.log(person2.name) // Kevin

proto

每一个JavaScript对象(除了 null )都具有的一个属性,叫proto,这个属性会指向该对象的原型

    function Person() {
    
    }
    var person = new Person();
    console.log(person.__proto__ === Person.prototype); // true

constructor

每个原型都有一个 constructor 属性指向关联的构造函数 实例原型指向构造函数

    function Person() {
    
    }
    console.log(Person === Person.prototype.constructor); // true

    function Person() {
    
    }
    
    var person = new Person();
    
    console.log(person.__proto__ == Person.prototype) // true
    console.log(Person.prototype.constructor == Person) // true
    // 顺便学习一个ES5的方法,可以获得对象的原型
    console.log(Object.getPrototypeOf(person) === Person.prototype) // true

实例与原型

    function Person() {
    
    }
    
    Person.prototype.name = 'Kevin';
    
    var person = new Person();
    
    person.name = 'Daisy';
    console.log(person.name) // Daisy
    
    delete person.name;
    console.log(person.name) // Kevin

在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 Daisy。

但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.proto ,也就是 Person.prototype中查找,幸运的是我们找到了 name 属性,结果为 Kevin。

原型与原型

原型链

    console.log(Object.prototype.__proto__ === null) // true

JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些

3. 闭包

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用 域之外执行。闭包是基于词法作用域书写代码时所产生的自然结果。

4. 性能意识(防抖、节流、事件代理、限制并发数)

5. 跨域

6. ES6

7. 深拷贝

8. 正则

9. 回流、重绘

10. 数据请求格式