this面试题

  • this的使用

严格模式

"use strict";
var foo = 123;
function fn() {
    console.log('print this is ', this);
    console.log(window.foo)
    console.log(this.foo);
}
console.log('global this is ', this);
fn();

打印如下
this面试题_第1张图片

  • 严格模式下,this不能执行window,指向undefined
  • 严格模式

链式调用

var obj1 = {
    a: 1,
    obj2: {
        a: 2,
        foo() {
            console.log(this.a)
        }
    }
}
obj1.obj2.foo() 

打印如下

2
  • 谁调用他,他就是谁,最终是obj2调用的,所以this就是obj2
  • 记住一个原则就是 this永远指向最后调用它的那个对象,如aa.bb.cc.dd.ee.func()
  • 打印为2

引用丢失

第一道面试题

a = 1
var obj = {
    a: 2,
    foo() {
        console.log(this.a)
    }
}
var foo = obj.foo;
obj.foo(); // 2
foo(); // 1
  1. 堆内存与栈内存
  2. 直接指向了函数,这个时候与obj这个对象没有关系,和直接声明没有什么关系了
name = 'javascript';
let obj = {
    name: 'obj',
    A() {
        this.name += 'this';
        console.log(this.name)
    },
    B(f) {
        this.name += 'this';
        f();
    },
    C() {
        setTimeout(function () {
            console.log(this.name);
        }, 1000);
    }
}
let a = obj.A;
a();
obj.B(function () {
    console.log(this.name);
});
obj.C();
console.log(name);
javascriptthis
javascriptthis
javascriptthis
javascriptthis
  1. 相当于var a = function{},然后直接调用
  2. 将函数当做参数,他相当于将函数复制给形参var f = function(){},直接调用函数,this执行window
  3. 也是函数当做参数传递,他会被setTimeout的形参赋值var setTimeoutParam = function(){},相当于直接调用函数,this指向window
  4. 由于前面的调用改变了window中的name属性,所以这里是javascriptthis

第二道面试题

var out = 25,
inner = {
    out: 20,
    func: function () {
        var out = 30;
        return this.out;
    }
};
console.log((inner.func, inner.func)());
console.log(inner.func());
console.log((inner.func)()); // 加了括号,正常代码执行顺序
console.log((inner.func = inner.func)());
  • 25,20,20,25
  1. (inner.func, inner.func)直接返回的就是inner.func执行的函数,相当于全局调用

绑定this

function foo() {
    console.log(this.a)
    return function () {
        console.log(this.a)
    }
}
var obj = { a: 1 }
var a = 2

foo()
foo.call(obj)
foo().call(obj)

换成bind会怎样

new

function Foo() {
    getName = function () { console.log(1); };
    return this;
}
Foo.getName = function () { console.log(2); };
Foo.prototype.getName = function () { console.log(3); };
var getName = function () { console.log(4); };
function getName() { console.log(5) };

Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
/*
2
4
1
1
2
3
3
*/
  • 优先级问题:new(带参数列表) = 成员访问 = 函数调用 > new(不带参数列表)

箭头函数

题目一

function User(name, age) {
    this.name = name;
    this.age = age;
    this.intro = function(){
        console.log('My name is ' + this.name)
    },
    this.howOld = () => {
        console.log('My age is ' + this.age)
    }
}

var name = 'Tom', age = 18;
var zc = new User('zc', 24);
zc.intro();
zc.howOld();

打印如下

My name is zc
index1.html:21 My age is 24

题目二

var name = 'window'
var obj1 = {
  name: 'obj1',
  intro: function () {
    console.log(this.name)
    return () => {
      console.log(this.name)
    }
  },
  intro2: () => {
    console.log(this.name)
    return function () {
      console.log(this.name)
    }
  }
}
var obj2 = {
  name: 'obj2'
}
obj1.intro.call(obj2)()
obj1.intro().call(obj2)
obj1.intro2.call(obj2)()
obj1.intro2().call(obj2)

打印如下

obj2
obj2
obj1
obj1
window
window
window
obj2

参考 点击

你可能感兴趣的:(interview,javascript,前端,开发语言)