1.js的预处理阶段,将声明方式的函数(指向函数的引用)和var定义的变量(undefined)放置在词法环境(全局环境指的是window)中;
2.命名冲突时,函数优先级更高。(不会被同名变量覆盖);
3.函数的参数(带传入的值)和argumengts对象优先添加入函数的词法环境;
4.创建函数时会创建自己的词法环境,与父函数形成作用域链,即child的词法环境[[scop]]指向parent的词法环境[[scope]]最终指向window;
5.在闭包中可以通过window.xx=xx将内部变量或方法导出;
6.闭包中的子函数在return出父函数后依然可以使用父函数的变量及参数;
7.若子函数没有引用任何父函数的变量或参数,则未形成闭包。静态作用域(闭包)的本质是嵌套函数与作用域链的结合;
8.闭包简单示例
function f(){ var a=0; return function(){ a++; console.log(a); } } var res=f(); res() ; //1 res(); //2
闭包不仅可以减少全局变量,也有利于封装,也可以减少传递给函数参数的数量,例如:
function calc(base) { return function (max) { let total=0; for(let i=1;i<=max;i++){ total+=i; } return total+base; } } let res=calc(2); console.log(res(3)); //基数为base 加上1到max的值的运算示例。
9.闭包捕获的变量是引用不是复制;父函数每调用一次就产生一个新的闭包(词法环境);
10.var res=p && p.address && p.address.home 是if(p)....的简写方法,若一个为空则都为空。若home有值则未home。
对象的set get方法示例:
let obj={ _age:18, get age(){ return this._age; }, set age(val){ if(val<0||val>150){ throw new Error(‘是人不?‘) }else{ this._age=val; } } }; obj.age=55; console.log(obj.age)
11.使用Object.defineProperty(p,‘newprop‘,{
value:99,writable:false,
}若不指定特性,则特性都为false,Object.defineProperties为对象的多个属性同时赋值和特性。(configurable writable enumerable value get set)
12.Object.keys(p) 返回一个数组,包含p对象的所有键值(不包括不可枚举的)(不包括继承的)。
p.hasOwnProperty(‘someprop‘)返回布尔值。Object.getOwnPropertyDescriptor(p,‘name‘)返回描述信息对象。
13.Function构造器的构造器指向它本身。(顶级),typeof() instanceof ;
14.工厂函数创建对象相对独立,占用内存较多;
15.公有的属性方法放入对象的原型属性(prototype)中;
16.Person.prototype.constructor===Person;
17.实例与构造器原型对象的连接方式为__proto__ 并非.constructor.prototype。伪类的本质是:实例创建出来后,构造函数和实例并没有什么关系了,
即使将构造函数的prototype对象修改掉,也不影响已经new过的实例(因为实例用__proto__和构造函数的原型对象保持引用关系),只能影响到以后new的实例。
18.this的指向问题:this是运行时指向;this在函数运行时谁调用就指向谁;用apply,call.bind改变this指向(apply和 call的区别只是apply的参数是数组。).bind()方法返回一个函数,并没有直接调用函数,apply和call直接调用了函数;bind()适合绑定事件等。
19.模拟new操作符:
function New(f) { //f是构造器函数 return function () { let o={‘__proto__‘:f.prototype}; f.apply(o,arguments); return o; } } let p=New(Person)(‘jiu‘,66);
20.Function的__proto__.__proto__指向Object,Object的__proto__最终指向Null。
21.构造函数即是方法也是对象,__proto__指向Function;
22.用for...in浅拷贝对象实现继承时,如果父对象内部嵌套对象,则拷贝的是嵌套对象的引用,修改子对象会影响到父对象。
23.[1,3,2]的tpyeof 是object,使用递归实现深拷贝:(使用递归的理由是处理对象中嵌套的对象或者数组,一直处理下去,解除引用关系。)
function extendDeeply(p,c={}) { for(let prop in p){ if(typeof p[prop]===‘object‘){ c[prop]=(p[prop].construct===Array)?[]:{}; extendDeeply(p[prop],c[prop]); }else{ c[prop]=p[prop]; } } }
24.由于F.prototype.constructor===F;所以:
let f = new F(); f.__proto__===f.constructor.prototype; //true; F.prototype.__proto__===F.prototype.constrctor.prototype //false
F.protoType.__proto__===Object.prototype; Function.prototype.__proto__===Object.prototype;
25.Object.create()的模拟实现:
function myCreate(p){ function F(){}; F.prototype=p; let ins=new F(); return ins; }
顶级对象是Object.prototype,顶级构造器是Function,以下是说明图:
26.(对象) instanceof (函数);
27.对象间建立继承关系可以使用C.prototype=Object.create(P.prototype); (相当于C.prototype=new P()的进化版);
28.继承四部:1 创建父类--->2 创建子类--->3 C.prototype=Object.create(P.prototype);C.prototype.constrctor=C;--->4 为子类的原型属性对象添加方法等。
29.子类的实例属性可以在构造函数中写P.apply(this,arguments);
30.p1.hasOwnProperty(‘name‘); P.prototype.isPrototypeOf(f); Object.getPropertyOf(f);
31.多态:利用arguments对象实现方法的重载(模拟参数的数目等决定函数的执行情况length,或者判断参数类型决定函数的执行情况typeof等)
32.重写:直接在子类中重新定义和父类同名的方法/属性。在子类中若要调用父类的方法可以创建C.super=P.prototype 然后在子类原型方法中调用,比如C.super.run();
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
33.回顾jQuery:$.extend({staticMethod:function(){console.log(‘1111‘)}})(添加静态方法); $.fn.extend({})(添加实例方法,相当于$.prototype.extend);
34.Jquery框架简易说明:在自调用立即执行函数中:用window.$和window.jQuery暴露$和jQuery给外部,jQuery.extend添加静态方法;jQuery.fn.extend添加实例方法
(function () { //暴露外部使用的借口 let jQuery=window.jQuery=window.$=function () {}; //处理原型对象 jQuery.fn=jQuery.prototype={} //静态和实例实现继承 jQuery.extend=jQuery.fn.extend=function () {}; //添加静态方法 jQuery.extend({}); //实现实例方法 jQuery.fn.extend({}); })();
35.用for循环或者Array.prototype.push.apply(o,divs)来创建简易的数组型对象;(并不是变成真正的数组,只是添加属性)
36.仿Jquery实现简单的选择器:
(function () { //暴露外部使用的借口 let jQuery=window.jQuery=window.$=function (selector) { return new jQuery.fn.init(selector); }; //处理原型对象 jQuery.fn=jQuery.prototype={ init:function(selector){ let ele=documents.getElementsByTagName(selector); Array.prototype.push.apply(this,ele); return this; }, jQuery:‘1.1.1‘, length:0; size:function(){ return this.length; } } //静态和实例实现继承 jQuery.extend=jQuery.fn.extend=function () {}; //添加静态方法 jQuery.extend({}); //实现实例方法 jQuery.fn.extend({}); })();
37.仿Jquery继承的简易实现:只有一个参数时可以用for..in this[p]=o[p];
38.仿Jquery添加静态方法:比如trim() noconflict()(通过用临时变量比如_$保存$ 然后恢复);
39.仿Jquery添加实例方法:比如get set each css
40.仿Jquery链式操作的简易实现:在函数最后一步return this即可。