JavaScript 是一门彻底的面向对象的语言。面向对象的概念:
1:一切事物皆对象
2:对象具有封装和继承特性
3:对象与对象之间使用消息通信,各自存在信息隐藏
面向对象的特点: 继承 封装 多态 抽象
一:封装
1:简单封装
生成实例对象的原始模式这样写的缺点是:一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。
2:原始模式
原始模式这种方法,可以解决代码重复的问题。但是,cat1和cat2之间没有内在的联系,不能反映出它们是同一个原型对象的实例。
3:构造函数模式
所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。
构造函数模式这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数。所以,
console.log(dog1.constructor == dog) //true
console.log(dog2.constructor == dog) //true
4:prototype模式
A:prototype 对象属性介绍:
prototypeobj1 obj2 obj3 都在prototype属性上面* prototype是js函数内设并且是自带的对象属性。prototype默认也有两个属性: constructor和__proto__。
* constructor指的是oof对象的本身,而__proto__指的是Object.prototype。
* prototype的作用是,当我们new一个函数的时候,prototype会用作new出来的这个对象 的原型。也就是__proto__,所以,可以给new出来的对象加属性赋值。
* 当实例化这个函数的时候,oofobj就等于oof函数里面的this,所以,会返回 2 1
B:prototype模式使用:
prototype模式当用这种方式声明函数的时候,有一个很大的弊端。那就是对于每一个实例对象, type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内 容,多占用一些内存。这样既不环保,也缺乏效率。所以,想让type属性和eat()方法在 内存中只生成一次。有一种方法就是用prototype属性。这意味着,我们可以把那些不 变的属性和方法,直接定义在prototype对象上。也就是 :
prototype模式这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对 象,因此就提高了运行效率。
二:继承
继承,顾名思义,子类集成父类的属性或者方法。怎样实现继承呢?下面将介绍构造函数的继承和非构造函数的继承。
1:构造函数的继承
A:第一种方法也是最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:
call 或者 applycall,apply方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])。
B:第一种方法是使用prototype属性。
prototype属性将Cats的prototype对象指向一个animal的实例。当于完全删除了prototype 对象原先的值,然后赋予一个新值。
Cats.prototype.constructor是指向Cats的;加了Cats.prototype.constructor = Cats这一行以后,指向作用就是将Cats的prototype属性指回Cats。
C:直接继承prototype
直接继承prototype将Cates的prototype对象,然后指向Animal的prototype对象,再用constryctor把属性指回Cates,这样就完成了继承。
说明:
B: student.prototype = Object.create(person.ptototype);Object.create的作用是创建一个空对象,这个对象的原型指向person.ptototype。那如果student.prototype = person.prototype; 这样的话,会导致给student增加属性的时候person也加上了该属性。
C:student.prototype.constructor = student; 这个constructor 的作用就是将student的prototype属性指回student.
三:原型链
1:并不是所有的函数都有prototype属性的,例如:
当Object.create()里面为null的时候,他就没有prototype属性。
网友评论