第一天
- 阅读下面的代码,问a.n的值是多少?
var a = {n : 1};
var b = a;
a.m = a = {m : 2};
console.log(a.m);
console.log(b.m);
console.log(a.n);
结果:
分析:结合图片进行解释:
结合图片,那么a.m的值应该为2,b.m的值应该是一个对象{m : 2 },a.n在新的a对象中没有n这个属性,所以应该是undefined。
2. 阅读下面的代码,问foo.constructor是?
function Foo(){
}
Foo.prototype = {value : "bar"};
var foo = new Foo();
console.log(foo.constructor);
结果:结果应该是Object。
分析:分析代码块可以知道,foo是Foo的一个实例,但是Foo的prototype进行了修改,不再是之前的Function,而是改成了{value : “bar”},这是一个对象,所以在追根溯源的时候,我们可以得出结论,对象的constructor应该是Object。
知识点加深记忆----对象以及函数的constructor:
- 函数
function Foo(){
}
var foo = new Foo();
console.log(foo.constructor);
console.log(foo);
结果:
2.对象
var obj = {a : 1};
console.log(obj.constructor);
console.log(obj);
结果:
总结:通过上面的验证可以得出一个结论,那就是函数的constructor是Funtion,对象的constructor就是Object,但是在分辨的时候要仔细分析代码块,因为js很灵活,可以自己改变protptyoe的指向,要具体问题具体分析。
3. 阅读下面的代码,问a的值是?
function Person(){
this.name = "bar";
return null;
}
var a = new Person();
console.log(a);
结果:
分析:既然a是由new关键字构造出来的,那么必然要返回一个对象,但是,由于Person函数返回的是null,所以说应该返回默认的this,所以应该是{name : bar}。
第二天
- 阅读下面的代码,说出最后的输出结果是什么?
function foo(){
this.count ++;
}
foo.count = 0;
for(var i = 0 ;i<10;i++){
if(i%5){
foo();
}
}
console.log(foo.count);
结果:
分析:首先应该分析for循环,函数声明之后必须进行调用之后才会执行,所以说,我们分析for循环,for循环一共执行了10次,每次i的值分别是0~9,然后i%5的值是:0,1,2,3,4,0,1,2,3,4,然后进行分析,0转化为Boolean是false不能执行,其他的都是整数都可以进行执行,所以说for循环执行了8次,但是我们再分析foo函数,可以知道this指向并不是foo,因为没有人进行调用,所以说this默认的应该是window,那么foo.count没有发生变化,最后的结果是0。
进行改写代码,可以得出for循环的执行次数(在全局声明一个计数器count)。
var count = 0;
function foo(){
this.count ++;
}
foo.count = 0;
for(var i = 0 ;i<10;i++){
if(i%5){
foo();
}
}
console.log(foo.count);
console.log(count);
输出结果:
2. 阅读下面的代码,在控制台会输出什么内容?
var name ="bar";
var obj = {
name : "obj",
show : function (){
console.log(this.name);
},
};
var foo = {
name : "foo",
}
obj.show.call(foo);
var show = obj.show;
show();
结果:
分析:前三个是声明了三个对象,然后观察下面的第一个执行语句obj.show.call(foo)这个代码改变了this的指向,从而相当于是foo.show()执行,所以说先输出foo。再看下面的取出obj.show方法,然后在全局调用,此时的this指向的应该是window,所以说,输出的应该是bar。
知识点:谁调用this,this就指向谁。
3.阅读下面的代码,指出控制台的打印的内容
var name = "foo";
var obj = {
name : "obj",
};
function change(name){
this.name = name;
}
var newChange = change.bind(obj);
newChange("bar");
console.log(name,obj.name);
结果:
分析:本题考察的知识点是call、apply、bind的区别。
call和apply是在函数调用的时候改变this,但是bind是返回一个带有明确this指向的函数,还可以绑定参数。所以说var newChange = change.bind(obj);这句话相当于是返回了一个函数
function newChange(name){
obj.name = name;
}
所以最后输出的第一个是window.name,第二个就是传入的参数bar。
加深记忆:bind 的特殊性。
var name = "foo";
var obj = {
name : "obj",
};
function change(name){
this.name = name;
}
//改变的代码块
var newChange = change.bind(obj,1);
newChange("bar");
console.log(name,obj.name);
结果:
注意:bar可以绑定参数!!!。
第三天
阅读下面的代码。并进行分析结果和原因
console.log(false == '0');
console.log(false === '0');
结果:
分析:首先考查的知识点是比较,双等于是弱比较,而三等于是强比较。在弱比较的时候,本质上都要转化为数字进行比较,false转化为数字是0,而字符串’0’转化为数字也是0,所以说而这项等,返回true。第二个是强比较,强比较先比较类型,false的类型是boolean,而"0"是string,二者必定不相等,所以是false。
知识点扩展
- 同种类型的比较
- 不同类型的比较(杂交,本质上转化为数字)
数字与字符串的比较,将字符串转化为数字,数字与布尔类型的比较,将布尔值转化为数字,布尔与字符串的比较,将二者都转化为数字。
特殊点:null == undefined 是true
第四天
阅读下面的代码,分析输出的结果及其原因
var length = 10;
function fn(){
console.log(this.length);
}
var obj = {
length :5,
method : function (fn){
fn();
arguments[0]();
}
}
obj.method(fn,1);
结果:
分析:先声明一个函数,长度,以及一个对象,分析下面的执行语句obj.method(fn,1)对象当中的函数执行,并且传入两个参数,一个是fn函数,一个是1,函数体内部fn()执行,this指向window,第二个函数执行,this指向的应该是arguments,所以说输出的length分别是10,2。
代码解释
var length = 10;
function fn(){
//改变点:此时输出this,看this指向谁
console.log(this);
}
var obj = {
length :5,
method : function (fn){
fn();
arguments[0]();
}
}
obj.method(fn,1);
结果