Node.js的对象模型

javaScript是一种基于原型的面向对象的语言,而不是面向类的面向的对象语言
C++、Java有类Class和实例Instance的概念,类是一类事物的抽象,而实例则是类的实体
JS是基于原型的语言,它只有原型对象的概念,原型对象就是一个模板,新的对象从这个模板创建从而获取最初的属性。任何对象在运行时可以动态的增加属性,而且,任何一个对象都可以作为另一个对象的原型,这样后者就可以共享前者的属性

定义类

字面式声明方式

var obj={
		property_1: value_1,
		property_2: value_2
		……
		“property n”: value_n	
}
var obj={
		x:1,
		1:'abc',
		'y':'123'
}
for (let s in obj)
		console.log(s,typeof(s))

这种方法也称作字面值创建对象
js 1.2开始支持

ES6之前–构造器

1、定义一个函数(构造器)对象,函数名首字母大写
2、使用this定义属性
3、使用new和构造器创建一个新对象

//定义类,构造器
function Point(x,y){
    this.x=x
    this.y=y
    this.show=()=>{console.log(this,this.x,this.y)}
    console.log('Point``````')    
}
console.log(Point)
p1=new Point(4,5)
console.log(p1)
console.log('--------------')
// 继承
function Point3D(x,y,z){
    Point.call(this,x,y)
    this.z=z
    console.log("Point3D~~~~~~~~~`")
}
console.log(Point3D)
p2=new Point3D(14,15,16)
console.log(p2)
p2.show()

在这里插入图片描述
new构建一个新的通用对象,new操作符会将新对象的this值传递给Point3D构造器函数,函数为这个对象创建z属性。
从上句话知道,new后得到一个对象,使用这个对象的this来调用构造器,那么如何执行基类的构造器方法,使用call方法,传入子类的this

ES6中的class

从ES6开始,新提供了class关键字,使得创建对象更加简单、清晰
1、类定义使用class关键字,创建的本质上还是函数,是一个特殊的函数
2、一个类只能拥有一个名为constructor的构造器方法,如果没有显式的定义一个构造方法,则会添加一个默认的constuctor方法
3、继承使用extends关键字
4、一个构造器可以使用super关键字来调用一个父类的构造函数
5、类没有私有属性

//基类定义
class Point{
    constructor(x,y){
        this.x=x
        this.y=y
    }
    show(){
        console.log(this,this.x,this.y)
    }
}
let p1=new Point(10,11)
p1.show()
//继承
class Point3D extends Point{
    constructor(x,y,z){
        super(x,y)
        this.z=z
    }
}
let p2=new Point3D(20,21,22)
p2.show()

在这里插入图片描述

重写方法

//基类定义
class Point{
    constructor(x,y){
        this.x=x
        this.y=y
    }
    show(){
        console.log(this,this.x,this.y)
    }
}
let p1=new Point(10,11)
p1.show()
//继承
class Point3D extends Point{
    constructor(x,y,z){
        super(x,y)
        this.z=z
    }
    // 重写
    show(){
        console.log(this,this.x,this.y,this.z)
    }
}
let p2=new Point3D(20,21,22)
p2.show()

在这里插入图片描述
子类中直接重写父类的方法即可
如果需要使用父类的方法,使用super.method()的方式调用

//基类定义
class Point{
    constructor(x,y){
        this.x=x
        this.y=y
        this.show=()=> console.log('Point')
    }
    // show(){
    //     console.log(this,this.x,this.y)
    // }
}
let p1=new Point(10,11)
p1.show()
//继承
class Point3D extends Point{
    constructor(x,y,z){
        super(x,y)
        this.z=z
        // this.show=()=> console.log('Point3D')
    }
    show(){
        console.log('Point3D')
    }
    
}
let p2=new Point3D(20,21,22)
p2.show()

在这里插入图片描述
上例优先使用了父类的属性show

//基类定义
class Point{
    constructor(x,y){
        this.x=x
        this.y=y
        // this.show=()=> console.log('Point')
    }
    show(){
        console.log(this,this.x,this.y)
    }
}
let p1=new Point(10,11)
p1.show()
//继承
class Point3D extends Point{
    constructor(x,y,z){
        super(x,y)
        this.z=z
        this.show=()=> console.log('Point3D')
    }
    show(){
        console.log('Point3D')
    }
    
}
let p2=new Point3D(20,21,22)
p2.show()

在这里插入图片描述
优先使用了子类的属性
总结
父类、子类使用同一种方式类定义属性或者方法,子类覆盖父类。
访问同名属性或方法时,优先使用属性

静态属性

静态属性目前还没有得到很好的支持
静态方法
在方法名前加上static,就是静态方法了

class Add{
    constructor(x,y){
        this.x=x
        this.y=y
    }
    static print(){
        console.log(this.x)
    }
}
add=new Add(40,50)
console.log(Add)
Add.print()
add.constructor.print()

在这里插入图片描述
静态方法中的this是Add类,而不是Add的实例
注意:
静态的概念和Python的静态不同,相当于Python中的类变量

this的坑

虽然js和C++、Java一样有this,但是Js的表现不同
原因在于,C++、Java是静态编译型语言,this是编译期绑定,而js是动态语言,运行期绑定

var school={
    name:'String',
    getNameFunc:function(){
        console.log(this.name)
        console.log(this)
        return function(){
            console.log(this===global)
            return this.name
        }
    }
}
console.log(school.getNameFunc()())

在这里插入图片描述
函数执行时,会开启新的执行上下文环境ExecutionContext
创建this属性,但是this是什么就要看函数是怎么调用的了
1、myFunction(1,2,3),普通函数调用方式,this指向全局对象,全局对象是nodejs的global或者游览器中的window
2、myObject.myFunction(1,2,3),对象方法的调用方式,this指向包含该方法的对象
3、call和apply方法调用,要看第一参数是谁
分析上例
String和{ name: ‘String’, getNameFunc: [Function: getNameFunc] }很好理解
第三行打印的true,是console.log(this===global)执行的结果,说明当前是global,因为调用这个返回的函数是直接调用,这就是个普通函数调用,所有this是全局对象
第四行undefined,就是因为this是global,没有name属性
这就是函数调用的时候,调用方式不同,this对应的对象不同
显式传入

name='111'
var school={
    name:'String',
    getNameFunc:function(){
        console.log(this.name)
        console.log(this)
        return function(that){
            console.log(this===global)
            return that.name
        }
    }
}
console.log(school.getNameFunc()(school))

在这里插入图片描述
通过主动传入对象,这样就避开了this的问题
ES3引入了apply、call方法

name='111'
var school={
    name:'String',
    getNameFunc:function(){
        console.log(this.name)
        console.log(this)
        return function(){
            console.log(this===global)
            return this.name
        }
    }
}
console.log(school.getNameFunc().call(school))

在这里插入图片描述
apply、call方法都是函数本身的方法,第一参数都是传入对象引入的
apply传其他参数需要使用数组
call传其他参数需要使用可变参数收集

function Print(){
    this.Print=function(x,y){
        console.log(x+y)
    }
}
p=new Print(1,2)
p.Print()
p.Print.call(p,10,20)
p.Print.apply(p,[10,20])

在这里插入图片描述
ES5引入了bind方法

name='111'
var school={
    name:'String',
    getNameFunc:function(){
        console.log(this.name)
        console.log(this)
        return function(){
            console.log(this===global)
            return this.name
        }
    }
}
var fuc=school.getNameFunc()
console.log(fuc)

var boundfunc=fuc.bind(school)
console.log(boundfunc)
console.log(boundfunc())

在这里插入图片描述
apply、call方法,参数不同,调用时传入this
bind方法是为了函数先绑定this,调用时直接用
ES6引入支持this的箭头函数

var school={
    name:'String',
    getNameFunc:function(){
        console.log(this.name)
        console.log(this)
        return ()=>{
            console.log(this===global)
            return this.name
        }
    }
}
console.log(school.getNameFunc()())

在这里插入图片描述
ES6新的定义方式

class school{
    constructor(){
        this.name='string'
    }
    getNameFunc(){
        console.log(this.name)
        console.log(this,typeof(this))
        return ()=>{
            console.log(this==global)
            return this.name
        }
    }
}
console.log(new school().getNameFunc()())

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值