Part Two
1.
// 原型、原型链检测
console.log(Function.__proto__ == Function.prototype); // true
console.log(Function.__proto__); // function
console.log(Function.prototype); // function
console.log(Object.__proto__); // function
function F(){}
var f = new F();
console.log(f.constructor); // F() 原型最初只包含constructor属性,而该属性也是共享的,因此可以通过对象实例访问
console.log(f.__proto__ == F.prototype); // true
console.log(f.prototype); // undefined
console.log(F.prototype); // Object {constructor: } 原型对象
console.log(F.__proto__);// function
console.log(F.__proto__.constructor); // Function
console.log(F._proto_ == F.prototype); // false
console.log(f.__proto__.__proto__); //Object
2.
//继承
function F1(){
this.f1property = true
}
F1.prototype.getF1property = function(){ // 原型方法
return this.f1property;
}
function F2(){
this.f2property = false
}
F2.prototype.getF2property = function(){ // 原型方法
return this.f2property
}
F2.prototype = new F1() // F2继承F1
var f2 = new F2()
console.log(f2.getF1property()); // true F2继承到了F1的原型方法
console.log(f2.f1property) // true
console.log(f2.f2property) // false
console.log(f2.getF2property()); // getF2property is not a function F2的原型被重写,getF2property已销毁
3.
// 闭包中的this问题
// 在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象
// But 匿名函数的执行环境具有全局性,因此其this对象通常指向window
var name = 'The window'
var obj = {
name:'The Object',
getName:function(){
return function(){
return this.name
}
}
}
console.log(obj.getName()()); // The window
// 全局执行了obj。getName()中的匿名函数
4.
// 模仿块级作用域
function outputNumbers(count){
(function(){
for(var i = 0;i<count;i++){
console.log(i)
}
})()
console.log(i)
}
outputNumber(5) // 0 - 4 i is not defined
// 在匿名函数内部定义的任何变量,都会在执行结束后被销魂
// 这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数
5.
// 私有变量,闭包 - 特权方法
function MyObject(){
var privateVariable = 10 // MyObject中的变量,外部不能访问
function privateFunction(){
return false
}
// 特权方法
this.pulicMethod = function(){
privateVariable++
return privateFunction()
}
}
var myObj = new MyObject()
console.log(myobj.publicMethod()) // false 通过调用MyObject中的特权方法,访问到MyObject中的变量方法
var myobj2 = new MyObject()
console.log(myobj.publicMethod == myobj2.publicMethod) // false -> 重新创建的publicMethod
// 假如上述this.去掉 -> myobj.publicMethod is not a function
6.
// 注意这2道题
function F(){
var f=[];
for(var i=0;i<=2;i++){
f[i]=i;
}
return f;
}
console.log(F()); // Array -> 0,1,2
function F(){
var f=[];
for(var i = 0;i<=2;i++){
f[i]=function(){
console.log(i);
}
}
return f;
}
var f = new F();
for(var i=0;i<f.length;i++){
f[i]();
};
// 3 3 3
// 第一题每次的循环中把i存入数组 所以每个下标对应的元素不会改
// 而第二题是存入数组的是方法,方法中打印i,而由于没有块级作用域,i会变成最后一次循环的i,也就是3。
// 所以整个数组每个下标对应方法的打印结果都为3
7.
function A(){
this.name = 'A'
this.say = function(){
console.log(this.name)
}
}
var a = new A() // this指向a
a.say() // A
console.log(a.name) // A
var say = a.say
say() // undefined -> 此时this指向全局,全局下没有a,所以undefined
var Say = a.say.bind(a)
Say() // A -> 显示绑定了a, this指向a
8.
function A(){
var i = 0
return function(){
console.log(i++)
}
}
var a = new A()
var b = new A()
a();// 0
a();// 1
b();// 0
b();// 1
// 两个示例不会共享i
9.
var obj1 = function(){
var a='1-1';
return{
a:'1-2',
say:function(){
console.log(a); // a不为1-2是因为 1-2的a是属性,需要通过对象访问
console.log(this.a);
}
}
}();
obj1.say();// 1-1 1-2
// 如果 var a = '1-1' 去掉,会报 a is not defined
10.
// 预解析问题
console.log(a); // function a(){..}
a(); // 10
var a=3;
function a(){
console.log(10);
}
console.log(a); // 3
a=6;
a(); // a is not a function
// 注意:函数提升比变量提升优先
// 最后a()报错是由于变量名a已经变成6,而非方法
console.log(a); // undefined
a(); // a is not a function
var a=3;
var a = function(){
console.log(10)
}
console.log(a); // function(){..}
a=6;
a(); // a is not a function
// 方法a已经变量声明的形式创建,所以优先级与变量提升一致
