es5 面向对象简易总结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es5 面向对象简易总结相关的知识,希望对你有一定的参考价值。

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即可。

 

以上是关于es5 面向对象简易总结的主要内容,如果未能解决你的问题,请参考以下文章

重新认识JavaScript面向对象: 从ES5到ES6

js ES5面向对象继承 模仿ES6

VSCode自定义代码片段——JS中的面向对象编程

VSCode自定义代码片段9——JS中的面向对象编程

JavaScript面向对象轻松入门之封装(demo by ES5ES6TypeScript)

前端 JavaScript 设计模式前奏--面向对象JQ实例与总结