整个JS执行环境是一个全局作用域,在全局声明变量相当于给window添加属性
函数内部构成一个局部作用域
全局为 0 级链,下面有 1 2 3 4…级
作用域在代码书写完了之后就确定了,与代码执行无关
访问变量时,先在自己的作用域查找,找不到就往上一级找
赋值的时候也是逐级向上找,如果在全局也没找到,则会自动在全局创建(隐式全局)
‘属性’ in obj :in 关键字用于查找属性是否存在于对象中,返回Boolean值
1.var声明的变量和声明的函数(function Fn(){})会被提前加载到内存中,相当于写在了最上面,所以又叫提升,注意,隐式全局不会提升
2.全局和函数体执行之前,全局和函数体都会进行预解析
var a = 1; function a(){};
/*实际上是:
var a;
function a (){};
a = 1;
*/
var a = 1 , b = 1 , c = 1; //相当于 var a = 1 ; var b = 1; var c = 1;
var a = b = c = 1; //相当于 var a = 1; b = 1 ; c = 1;
函数与变量重名,函数的优先级要比变量高,函数会把变量覆盖
对象就是用来存储数据的无序的集合,存储在对象身上的数据,每一个都有一个名字,称为属性,又叫键,实际应用中,为了方便,把属性分为两类,值为函数的叫做方法,值为非函数的叫属性。
var person = {
name : 'kemp',
age : 22,
sayName = function () {
//...函数体...
}
}
简单来说,构造函数就是函数配合new关键字使用,如:new Fn(){}
function Person (name , age){
this.name = name;
this.age = age;
this.sayName = function (){
//函数体...
}
}
var kemp = new Person('kemp' , 23);
/*
kemp 相当于{
name : 'kemp',
age : 23,
sayName = function (){
//函数体...
}
}
*/
构造出来的对象kemp称之为构造函数Person的实例
new 的作用相当于: 创建一个新的空对象 调用函数 this指向新对象 返回新创建出来的对象
每一个函数在内存中都对应有一个对象,这个对象是通过函数的 prototype 属性可以访问到,称之为原型对象
实例找方法找属性,如果自己没有,默认去找原型对象调取,如果自己有,则用自己的
function Person (name , age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(this.name);
}
var zhangSan = new Person('zs', 18);
zhangsan.sayName();
每一个函数都有一个原型对象
函数的原型对象可以通过函数的 .prototype
属性访问到 函数 .prototype =>原型对象
函数的实例默认可以访问到函数的原型对象
原型对象的 .constructor
属性指向自己的函数 原型对象.constructor => 函数
实例的.__proto__
属性指向原型对象 实例.proto => 原型对象 (非标准,不建议上线使用)
原型对象的构造函数是Object()
实例-原型对象-原型对象的原型对象(Object)称为原型链
Object拥有很多的方法,同时是对象之源,所以所有的对象都能够调用里面的方法
Object再往上就是null了
先自身查找,找不到就沿着原型链往上找,若一直到null,返回undefined
个性的属性放在函数内,共性的属性放在原型对象上
原型对象的使用方式:新定义一个原型对象并指向(会舍弃原有原型对象)
Person.prototype = {
constructor : Person,//一定要写!!!
sayName : function(){},
type : 'human'
}