原型
原型链与继承:
js的每一个对象都有一个内置的_proto_属性.当一个对象需要引用一个属性时,js engine首先从这个对象自身的属性表中寻找属性标识,如果没找到,就在_proto_这个属性引用的对象中查找,直到找到或者_proto_属性引用为null为止.
js的函数都有一个默认的属性prototype, 这个prototype属性是一个对象,这个对象有个属性叫做constructor属性,constructor属性引用函数自身. ==> f.prototype.constructor === f
我们在用new操作符时,会为构造函数返回一个新的对象. var m = new f().我们根据对象都会有_proto_属性,并且这个_proto_属性引用构造函数f的prototype属性.
var obj = new Func();
obj.contructor == Func; //true
分析上端代码串,obj为new出来的新对象,obj的_proto_属性引用Func的prototype属性.
变量声明提升
大前提:可以使用var来定义变量,如果没有赋值,那么初始值为undefined,所有不使用var定义的变量都视为全局变量;
声明提前(hoisting) ==>
如: var scope = 'global';
function f() {
console.log(scope);
var scope = 'local';
console.log(scope);
}
首先 scope在第一行被声明为全局变量,可是函数体内有局部变量,所以外部的scope = 'gobal'不起作用,被覆盖掉。但是由于变量提前,并不会因为第三行输出一个之前未声明的scope而报错,而是等同于下代码:
var scope = 'global';
function f() {
var scope; //由于下边有scope的赋值,这里默认声明了一个 undefined的scope变量
console.log(scope);
var scope = 'local';
console.log(scope); //local
}
比较一下两段代码:
var getName = function() { //变量赋值的函数=>函数表达式语法
console.log(2);
}
function getName () { //
函数声明
的函数
console.log(1);
}
getName();
这里涉及到函数声明提升的问题,当
getName()时,会把函数声明的代码段上升到最顶端,如:
var getName; //变量提升
function getName() { //函数声明提升
console.log(1);
}
getName = function() {
console.log(2);
}
getName(); //输出为2
再看一段例子:
f('superman'); funtion f(name) {
function f(name) {
console.log(name);
console.log(name); ====>
}
}
f('superman');
----------------------------------------------------------
f('superman'); var f;
var f = function(name) { ====> f('superman');
console.log(name);
f = function (name) {
}
console.log(name);
} //报错