资讯专栏INFORMATION COLUMN

javascript基础篇:关于js面向对象的理解

newtrek / 1589人阅读

摘要:关于中面向对象的理解面向对象编程它是一种编程思想我们的编程或者学习其实是按照类实例来完成的学习类的继承封装多态封装把实现一个功能的代码封装到一个函数中一个类中以后再想实现这个功能,只需要执行这个函数方法即可,不需要再重复的编写代码。

关于js中面向对象的理解
面向对象编程(oop)
它是一种编程思想  (object-oriented programming ), 我们的编程或者学习其实是按照类、实例来完成的

学习类的继承、封装、多态

封装

把实现一个功能的代码封装到一个函数中(一个类中),以后再想实现这个功能,只需要执行这个函数方法即可,不需要再重复的编写代码。

低耦合,高内聚
减少页面中的冗余代码,提高代码的重复使用率

多态

一个类(函数)的多种形态:重载、重写

【重载】
后台java,c#等编程语言中,对于重载的概念:方法名相同参数不同,叫做方法的重载

public void sum(int num1,int num2){
    //=> CODE
}
public void sum(int num1){
    //=>CODE
}
public void sum(int num1,string str){
    //=>CODE
}
sum(12,23) //第一个
sum(12) //第二个
sum(12,"word") //第三个
JS中没有类似于后台严格意义上的重载,JS中如果方法名相同,最后只能保留一个(和实参没有关系)
JS中的重载:同一个方法,通过传递实参的不同(arguments)我们完成不同的功能,我们把这个也理解为重载
function sum(num1,num2){
    return num1+num2;
}
function sum(){
    var ary=Array.prototype.slice.call(arguments)
    return eval(ary.join("+"));
}
sum(10,20)
sum(10,20,30);// =>不管哪一次执行的都是第二个sum
不管是后台语言还是js都有重写:子类重写父类的方法
类的继承
什么是继承?
子类继承父类中的一些属性和方法

1.原型继承

让子类的原型指向父类的实例
Children.prototype=new Parent();
function Parent(){
    this.x=10;
}
Parent.prototype.getX=function(){
    console.log(this.x)
}

function Child(){

    this.y=20;
}
Child.prototype=new Parent(); //最好都在扩展子类原型方法之前执行
Child.prototype.constructor=Child;
Child.prototype.getY=function(){
    console.log(this.y);
}
var child=new Child();
console.log(child.y);
child.getY();
child.getX()
console.log(child.x);

[细节]
1.我们首先让子类的原型指向父类的实例,然后再向子类原型上扩展方法,防止提前增加方法,等原型重新指向后,之前在子类原型上扩展的方法失效(子类原型已经指向新的空间地址了)
2.让子类原型重新指向父类实例,子类原型上原有的constructor就没有了,为了保证构造函数的完整性,我们最好给子类的原型重新设置constructor属性值:Children.prototype.constructor=Children
[原理]
原型继承,并不是把父类的属性和方法copy一份给子类,而是让子类的原型和父类原型之间搭建一个链接的桥梁,以后子类或者子类的实例可以通过原型链的查找机制,找到父类原型上的方法,从而调取这些方法使用即可。

[特征]
子类不仅可以继承父类原型上的公有属性方法,而且父类提供给实例的那些私有属性的方法,也被子类继承了(存放在子类原型上,作为子类公有的属性和方法)

2.call继承

在子类的构造体中,把父类做普通方法执行,让父类方法中this指向子类的实例
function Parent(){
    this.x=10;
}
Parent.prototype.getX=function(){
    console.log(this.x);
}
function Children(){
    //=>this:child 子类的实例
    Parent.call(this); //让Parent执行,方法中的this依然是子类中的实例(在父类构造体中写this.xxx=xxx都相当于给子类的实例增加一些私有的属性和方法)
    this.y=20;
}
var child=new Children();
console.log(child.x);
【原理】
把父类构造体中私有的属性和方法,原封不动复制了一份给子类的实例(继承完成后,子类和父类是没有关系的);公有的无法继承。

【细节】
我们一般把call继承放在子类构造体的第一行,也就是创建子类实例的时候,进来的第一件事就是先继承,然后再给实例赋值自己私有的(好处:自己的可以把继承过来的结果替换掉--如果有重复的情况下)

3.寄生组合继承

Object.create: 创建一个空对象,把obj作为新创建对象的原型  低版本不兼容
var obj={name:"hello word"}
var newObj=Object.create(obj);
newObj.__proto__===obj
寄生组合式继承完成了一个需求
子类公有的继承父类公有的(原型继承的变通)
子类私有的继承父类私有的(call继承完成)
function Parent(){
    this.x=10;
}
Parent.prototype.getX=function(){
    console.log(this.x)
}
function Children(){
    Parent.call(this)
    this.y=20;
}
Children.prototype=Object.create(Parent.prototype);
Children.prototype.constructor=Children;
Children.getY=function(){
    console.log(this.y);
}
var child=new Children();
console.log(child.x);
child.getX()


自己实现一个类似于Objcet.create的方法
Object.myCreate=function myCreate(obj){
    var Fn=new Function();
    Fn.prototype=obj;
    return new Fn();
}
var oo={name:"o"}
Object.myCreate(oo)

4.ES6中的类和继承

class Fn{
    constructor(a){
        //=>constructor:Fn
        //=>这里面的this.xxx=xxx是给当前实例设置的私有属性
        this.xxx=a
    }
    //=>这里设置的方法都放在Fn.prototype上(给实例提供的公有属性方法)    
    //=>getX $ setX:都是给Fn.prototype设置方法
    getx(){

    }
    setX(){

    }
    //=>static 这些属性和方法都是Fn当做普通对象设置的私有属性和方法,和实例没有任何的关系
    static private(){

    }
}
let f=new Fn(10,20);
继承
class A{
    constructor(){
        this.x=10
    }
    getX(){
        console.log(this.x);
    }
}

class B extends A{
    constructor(){
        super(); //=>原理call继承, 第一句必须写上super() 
        this.y=20;
    }
    getY(){
        console.log(this.y);
    }
}
let b=new B();

5.for in循环遍历细节问题

Object.prototype.hasPubProperty=function hasPubProperty(){

}
/*
* for in循环 不仅可以遍历当前对象(或者当前实例)所有的私有属性和方法,还可以把原型上自己创建的公共属性方法进行遍历
*
* for 只会遍历私有的属性和方法(更多的是索引),自己在原型上扩展的方法不会被遍历出来
* */

var obj={name:"tom",age:8}
for (const objKey in obj) { //webstorm 快捷键 itin
    if(obj.hasOwnProperty(objKey)){
        console.log(objKey);
    }
    // console.log(objKey); // hasPubProperty
}
var ary=[12,23,34];
for (let i = 0; i < ary.length; i++) {
    console.log(ary[i]);
}

for (const aryKey in ary) { //快捷键 itar
    console.log(ary[aryKey]);
}

webStorm自己配置快捷键 file-> setting->liveTemplates 右侧+自己DIY

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/53794.html

相关文章

  • javascript基础关于js面向对象理解

    摘要:关于中面向对象的理解面向对象编程它是一种编程思想我们的编程或者学习其实是按照类实例来完成的学习类的继承封装多态封装把实现一个功能的代码封装到一个函数中一个类中以后再想实现这个功能,只需要执行这个函数方法即可,不需要再重复的编写代码。 关于js中面向对象的理解 面向对象编程(oop) 它是一种编程思想 (object-oriented programming ), 我们的编程或者学习其...

    roadtogeek 评论0 收藏0
  • 【连载】前端个人文章整理-从基础到入门

    摘要:个人前端文章整理从最开始萌生写文章的想法,到着手开始写,再到现在已经一年的时间了,由于工作比较忙,更新缓慢,后面还是会继更新,现将已经写好的文章整理一个目录,方便更多的小伙伴去学习。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 个人前端文章整理 从最开始萌生写文章的想法,到着手...

    madthumb 评论0 收藏0
  • SegmentFault 技术周刊 Vol.32 - 七夕将至,你对象”还好吗?

    摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...

    李昌杰 评论0 收藏0

发表评论

0条评论

newtrek

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<