(一)、call,apply,bind 的用法与区别?
答案:摘自:https://www.cnblogs.com/Jade-Liu18831/p/9580410.html(总结的特别棒的一篇文章)
(二)、理解 JavaScript 作用域(以及闭包)?
答案:摘自:http://www.cnblogs.com/syfwhu/p/4839562.html
(三)、理解 this 关键词(全局,函数和对象范围)?
答案:按照this
指针的优先级,列出下面常会遇到的四种情况,从上到下依次是优先级从高到低(后面会详细比较优先级)。
- 函数是和
new
一起被调用的吗(new绑定)?如果是,this
就是新构建的对象。var bar = new foo()
- 函数是用
call
或apply
被调用(明确绑定),甚至是隐藏在bind
硬绑定 之中吗?如果是,this
就是明确指定的对象。var bar = foo.call( obj2 )
- 函数是用环境对象(也称为拥有者或容器对象)被调用的吗(隐含绑定)?如果是,
this
就是那个环境对象。var bar = obj1.foo()
- 否则,使用默认的
this
(默认绑定)。如果在strict mode
下,就是undefined
,否则是global
对象。var bar = foo()
以上,就是理解对于普通的函数调用来说的this
绑定规则所需的全部。是的···几乎是全部。
(四)、掌握原型继承?
答案:
古典继承在 JavaScript 中被模拟。它是使用了原型方法。在 ES5,ES6 中看到的所有新的 class 语法都只是包裹在底层原型 OOP 的语法糖。使用 JavaScript 函数就能创建类。
var animalGroups = {
MAMMAL: 1,
REPTILE: 2,
AMPHIBIAN: 3,
INVERTEBRATE: 4
};
function Animal(name, type) {
this.name = name;
this.type = type;
}
var dog = new Animal("dog", animalGroups.MAMMAL);
var crocodile = new Animal("crocodile", animalGroups.REPTILE);
在这里我们给类创建对象(通过 new 关键字)。我们可以给这些指定的类(函数)添加方法。添加类的方法可以是这样:
Animal.prototype.shout = function() {
console.log(this.name + 'is ' + this.sound + 'ing...');
}
这里你可能会有疑问。类中并没有 sound 属性。对!这里根本没有定义 sound 属性。它是由继承父类的子类传递的。
在 JavaScript 中,继承是这样实现的:
function Dog(name, type) {
Animal.call(this, name, type);
this.sound = "bow";
}
定义一个更具体的函数 Dog。在这里,为了继承 Animal 类,我们需要引用 call 函数(上面讨论过)来传递 this 和其他参数。我们可以通过以下方法来实例化 German Shepard。
var pet = Dog("germanShepard", animalGroups.MAMMAL);
console.log(pet); // returns Dog {name: "germanShepard", type: 1, sound: "bow"}
我们并没有在子函数中声明 name 和 type, 而是调用了 Animal 函数并设置相应的属性。pet 从父类那里获得了属性(name, type)。那么方法也能继承吗?让我们一起来看看!
pet.shout(); // Throws error
什么?为什么会这样?出现这种情况是因为 JavaScript 不能继承父类的方法。如何解决这个问题呢?
// Link prototype chains
Dog.prototype = Object.create(Animal.prototype);
var pet = new Dog("germanShepard", animalGroups.MAMMAL);
// Now shout method is available
pet.shout(); // germanShepard is bowing...
像现在这样 shout 方法是可用的。我们可以通过 object.constructor 函数来检查 JavaScript 中指定对象的类。让我们看看 pet 的类是什么。
pet.constructor; // returns Animal
这个答案不够准确。Animal 是一个父类。但 pet 到底是什么类型?它属于 Dog 类型。这是因为 Dog 类的构造函数。
Dog.prototype.constructor; // returns Animal
返回 Animal。我们应该把它设置为 Dog 类本身,如此一来,类的所有实例(对象)会指向它从属于的正确类名。
Dog.prototype.constructor = Dog;
关于原型继承,请记住以下四点:
-
类属性用this界定
-
类方法使用prototype对象界定
-
继承属性,请使用call函数传递this对象
-
继承方法,请使用Object.create连接父类和子类的原型
-
始终将子类构造函数设置为自身,以获取对象的正确标识
在 JS 中,call 函数和 prototype 对象造就了继承。
(五)理解回调函数和 promises?
答案:摘自:https://www.jianshu.com/p/25d05a3ba7be
(六) Javascript继承机制的设计思想?
答案:摘自:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html (阮一峰大拿所写,通俗易懂,非常喜欢)
(七) 其他面试题目
答案:摘自:https://github.com/Advanced-Frontend/Daily-Interview-Question/blob/master/datum/summary.md
温馨提示:不积跬步,无以至千里;不积小流,无以成江海。
——荀子《劝学篇》