预编译:函数声明整体提升
变量 声明提升
- 任何变量未经声明就赋值,此变量为全局对象所有。var a=123; var a = b = 123;(a b为全局对象)
- 一切声明的全局变量,全是window的属性。
function fn(a) { console.log(a);//function a(){} var a = 123; console.log(a);//123 function a() {} console.log(a);//123 console.log(b);//undefined var b = function () {} console.log(b);//function(){} } fn(2);
- 创建AO对象
- 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
- 将实参值和形参相统一
- 在函数体里找函数声明,值赋予函数体
AO{
a:function(){}
b:undefined
}
作用域链:作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。
闭包:指有权访问另一个函数作用域中变量的函数,可以访问另外一个函数的局部变量,延申了变量的作用范围,
闭包会导致原有作用域不释放,造成内存泄露。
作用:1.实现公有变量 :函数累加器
2.可以做缓存 eater
3.实现封装,属性私有化 Person()
3.模块化开发,防止污染全局变量
function a() { var num = 100; function b() { num++; console.log(num); } return b; } var demo = a(); demo();//101 demo();//102
2.
function test() { var num = 100; function a() { num++; console.log(num); } function b() { num--; console.log(num); } return [a,b]; } var myArr =test(); myArr[0]();//101 myArr[1]();//100 function Person(name,age,sex) { var a=0; this.name =name; this.age=age; this.sex=sex; function sss() { a++; document.write(a); } this.say=sss; } var oPerson=new Person(); oPerson.say();//1 oPerson.say();//2 var oPerson1=new Person(); oPerson1.say();//1
立即执行函数(针对初始化功能):(function (){}());W3C建议这种
(function (){})();
只有表达式才能被执行符号执行
原型:1.原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法,原型也是对象。
2.利用原型特点和概念,可以提取公有属性
3.对象查看原型:隐式属性__proto__
function Person(){ var this={__proto__:Person.prototype}; }
4.对象查看对象的构造函数:constructor
原型链:1.原型链构成
2.原型链上属性的增删改查
3.绝大多数对象的最终都会继承自Object.prototype
(create(null)例外,因为没有原型)
4.Object.create(原型)
var obj ={name : "123"}; var obj1 = Object.create(obj);//obj1的原型是obj obj1.name==123
Son.prototype.name = "Deng"; function Son(name) { this.name = name; } var son = new Son("123"); 查看属性:son.name "123" Son.prototype.name "Deng" son.__proto__.name “Deng” 修改属性:son.name="456" "456" son.name "456" 增加属性:son.Last="111" "111" son.Last "111" 删除属性:delete son.Last true son.Last undefined
/工厂化开发继承 Son.prototype = { name : "Deng", sex : "male" }; function Son(age) { this.age = age; } var son = new Son("23"); 控制台: son.sex "male" son.name "Deng" son.age "23"
改变原型: Son.prototype.name="123" function Son(age) { this.age = age; } var obj={ name : "aaa" } var son = new Son("23"); 控制台: son.__proto__ {name: "123", constructor: ƒ} son.__proto__=obj {name: "aaa"} son.name "aaa" 顺序: Son.prototype.name="123" function Son() { } //Son.prototype.name="999" var son = new Son(); //Son.prototype.name="999" 控制台:Son.prototype.name=”999” Son.prototype.name="123" function Son() { } var son = new Son(); //Son.prototype={name:"999"} 控制台:Son.prototype.name=”123” 原理,var this={__proto__:Son.prototype} Son.prototype改了,__proto__没变 //a.sayName() sayName里面的this指向是,谁调用的这个方法,this就指向谁 虽然不是你的this但是你调用了就是你的 Son.prototype = { name : "a", sayName: function () { console.log(this.name); } } function Son() { this.name = "b"; } var son = new Son(); //son.sayName() == b //Son.prototype.sayName == a Son.prototype = { height : 100 } function Son() { this.eat = function () { this.height ++; } } var son = new Son();//son自身增加height属性并加1,不影响原型属性,还是100 控制台: son.eat() undefined son Son {height: 101, eat: ƒ} son.__proto__ {height: 100}
原型链:传统原型链: function Grand() { } Facher.prototype = grand; var grand = new Grand(); function Facher() { } var father = new Father(); Son.prototype = father; function Son() { } var son = new Son(); 工业模式:1.不能继承借用构造函数的原型 2.每次构造函数都要多走一个函数 function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } function Student(name, age, sex, grade) { Person.call(this,name,age,sex); this.grade = grade; } var student = new Student();
公有原型:Father.prototype.Name="Deng" function Father() { } function Son() { } Son.prototype=Father.prototype; var son = new Son(); var father = new Father()
(最优)圣杯模式: function inherit(Target, Origin) { function F() {}; F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constructor = Target; Target.prototype.uber = Origin.prototype; } Father.prototype.Name = "Deng"; function Father() { } function Son() { } inherit(Son,Father); var son = new Son(); var father = new Father(); A instanceof B :看A 对象的原型链上 有没有 B的原型
this的四种情况:
- 当函数调用(预编译)时指向window
- 当方法调用时指向调用对象 obj.func(); func()里面的this指向obj
- apply/call指向第一个参数
- 构造函数调用指向实例对象
var name = "222"; var a = { name : "111", say : function () { console.log(this.name); } }