面向对象的三大基本特性

封装(把相关的信息(无论数据或方法)存储在对象中的能力)
继承(由另一个类(或多个类)得来类的属性和方法的能力)
多态(一个对象在不同情况下的多种形态)
定义类或对象
第一种:基于Object对象
var person = new Object();
person.name = "Rose";
person.age = 18;
person.getName = function () {
return this.name;
};
console.log(person.name);//Rose
console.log(person.getName);//function () {return this.name;}
console.log(person.getName());//Rose
缺点:不能创建多个对象。
第二种:基于字面量方式
var person = {
name : "Rose",
age : 18 ,
getName : function () {
return this.name;
}
};
console.log(person.name);//Rose
console.log(person.getName);//function () {return this.name;}
console.log(person.getName());//Rose
优点:比较清楚的查找对象包含的属性和方法;
缺点:不能创建多个对象。
第三种:工厂模式
方式一:
function createPerson(name,age) {
var object = new Object();
object.name = name;
object.age = age;
object.getName = function () {
return this.name;
};
return object;
}
var person1 = createPerson("Rose",18);
var person2 = createPerson("Jack",20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName);//false//重复生成函数,为每个对象都创建独立的函数版本
优点:可以创建多个对象;
缺点:重复生成函数getName(),为每个对象都创建独立的函数版本。
方式二:
function createPerson(name,age) {
var object = new Object();
object.name = name;
object.age = age;
object.getName = getName;
return object;
}
function getName() {
return this.name;
}
var person1 = createPerson("Rose",18);
var person2 = createPerson("Jack",20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName);//true//共享同一个函数
优点:可以创建多个对象;
缺点:从语义上讲,函数getName()不太像是Person对象的方法,辨识度不高。
第四种:构造函数方式
方式一:
function Person(name,age) {
this.name = name;
this.age = age;
this.getName = function () {
return this.name;
}
}
var person1 = new Person("Rose",18);
var person2 = new Person("Jack",20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName); //false//重复生成函数,为每个对象都创建独立的函数版本
优点:可以创建多个对象;
缺点:重复生成函数getName(),为每个对象都创建独立的函数版本。
方式二:
function Person(name,age) {
this.name = name;
this.age = age;
this.getName = getName ;
}
function getName() {
return this.name;
}
var person1 = new Person("Rose",18);
var person2 = new Person("Jack",20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName); //true//共享同一个函数
优点:可以创建多个对象;
缺点:从语义上讲,函数getName()不太像是Person对象的方法,辨识度不高。
第五种:原型方式
function Person() {
}
Person.prototype.name = 'Rose';
Person.prototype.age = 18;
Person.prototype.getName = function () {
return this.name;
};
var person1 = new Person();
var person2 = new Person();
console.log(person1.name);//Rose
console.log(person2.name);//Rose//共享同一个属性
console.log(person1.getName === person2.getName);//true//共享同一个函数
缺点:它省略了为构造函数传递初始化参数,这在一定程序带来不便;另外,最主要是当对象的属性是引用类型时,它的值是不变的,总是引用同一个外部对象,所有实例对该对象的操作都会影响其它实例:
function Person() {
}
Person.prototype.name = 'Rose';
Person.prototype.age = 18;
Person.prototype.lessons = ["语文","数学"];
Person.prototype.getName = function () {
return this.name;
};
var person1 = new Person();
person1.lessons.push("英语");
var person2 = new Person();
console.log(person1.lessons);//["语文", "数学", "英语"]
console.log(person2.lessons);//["语文", "数学", "英语"]//person1修改影响了person2
第六种:构造函数+原型方式(推荐)
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.getName = function () {
return this.name;
};
var person1 = new Person('Rose', 18);
var person2 = new Person('Jack', 20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName);//true//共享原型中定义的方法
缺点:属性定义在构造函数内,方法定义在构造函数外,与面向对象的封装思想不符。
第七种:构造函数+动态原型方式(推荐)
方式一:
function Person(name,age) {
this.name = name;
this.age = age;
if (typeof Person._getName === "undefined"){
Person.prototype.getName = function () {
return this.name;
};
Person._getName = true;
}
}
var person1 = new Person('Rose', 18);
var person2 = new Person('Jack', 20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName);//true//共享原型中定义的方法
方式二:
function Person(name,age) {
this.name = name;
this.age = age;
if (typeof this.getName !== "function"){
Person.prototype.getName = function () {
return this.name;
};
}
}
var person1 = new Person('Rose', 18);
var person2 = new Person('Jack', 20);
console.log(person1.name);//Rose
console.log(person2.name);//Jack
console.log(person1.getName === person2.getName);//true//共享原型中定义的方法
对象属性的扩展及删除
Javascript的对象可以使用 '.' 操作符动态的扩展其属性,可以使用 'delete' 关键字或将属性的值设置为 'undefined' 来删除属性。
function Person(name,age) {
this.name = name;
this.age = age;
if (typeof Person._getName === "undefined"){
Person.prototype.getName = function () {
return this.name;
};
Person._getName = true;
}
}
var person = new Person("Rose",18);
person.job = 'Engineer';//添加属性
console.log(person.job);//Engineer
delete person.job;//删除属性
console.log(person.job);//undefined//删除属性后值为undefined
person.age = undefined;//删除属性
console.log(person.age);//undefined//删除属性后值为undefined
对象属性类型
数据属性
特性:
[configurable]:表示能否使用delete操作符删除从而重新定义,或能否修改为访问器属性。默认为true;
[enumberable]:表示是否可通过for-in循环返回属性。默认true;
[writable]:表示是否可修改属性的值。默认true;
[value]:包含该属性的数据值。读取/写入都是该值。默认为undefined;如上面实例对象person中定义了name属性,其值为'My name',对该值的修改都反正在这个位置
function Person(name,age) {
this.name = name;
this.age = age;
if (typeof Person._getName === "undefined"){
Person.prototype.getName = function () {
return this.name;
};
Person._getName = true;
}
}
var person = new Person("Rose",18);
Object.defineProperty(person,"name",{configurable:false,writable:false});
person.name = "Jack";
console.log(person.name);//Rose//重新赋值无效
delete person.name;
console.log(person.name);//Rose//删除无效
注意:
一旦将configurable设置为false,则无法再使用defineProperty将其修改为true(执行会报错:cannot redefine property : propertyName)
function Person(name,age) {
this.name = name;
this.age = age;
if (typeof Person._getName === "undefined"){
Person.prototype.getName = function () {
return this.name;
};
Person._getName = true;
}
}
var person = new Person("Rose",18);
Object.defineProperty(person,"name",{configurable:false,writable:false});
person.name = "Jack";
console.log(person.name);//Rose//重新赋值无效
delete person.name;
console.log(person.name);//Rose//删除无效
Object.defineProperty(person,"name",{configurable:true,writable:true});//Cannot redefine property: name
访问器属性
特性:
[configurable]:是否可通过delete操作符删除重新定义属性;
[numberable]:是否可通过for-in循环查找该属性;
[get]:读取属性时调用,默认:undefined;
[set]:写入属性时调用,默认:undefined;
访问器属性不能直接定义,必须使用defineProperty()或defineProperties来定义:如下
function Person(name,age) {
this.name = name;
this._age = age;
if (typeof Person._getName === "undefined"){
Person.prototype.getName = function () {
return this.name;
};
Person._getName = true;
}
}
var person = new Person("Rose",18);
Object.defineProperty(person,"age",{
get:function () {
return this._age;
},
set:function (age) {
this._age = age;
}});
person.age = 20;
console.log(person.age);//20//person.age=20是使用set方法将20赋值给_age,person.age是使用get方法将_age的读取出来
console.log(person._age);//20
获取所有的属性和属性的特性
使用Object.getOwnPropertyNames(object)方法可以获取所有的属性;
使用Object.getOwnPropertyDescriptor(object,property)方法可以取得给定属性的特性;
function Person(name,age) {
this.name = name;
this._age = age;
if (typeof Person._getName === "undefined"){
Person.prototype.getName = function () {
return this.name;
};
Person._getName = true;
}
}
var person = new Person("Rose",18);
Object.defineProperty(person,"age",{
get:function () {
return this._age;
},
set:function (age) {
this._age = age;
}});
console.log(Object.getOwnPropertyNames(person));//["name", "_age", "age"]
console.log(Object.getOwnPropertyDescriptor(person,"age"));//{enumerable: false, configurable: false, get: function, set: function}
对于数据属性,可以取得:configurable,enumberable,writable和value;
对于访问器属性,可以取得:configurable,enumberable,get和set;
继承机制实现
对象冒充
function Father(name) {
this.name = name ;
this.getName = function () {
return this.name;
}
}
function Son(name,age) {
this._newMethod = Father;
this._newMethod(name);
delete this._newMethod;
this.age = age;
this.getAge = function () {
return this.age;
}
}
var father = new Father("Tom");
var son = new Son("Jack",18);
console.log(father.getName());//Tom
console.log(son.getName());//Jack//继承父类getName()方法
console.log(son.getAge());//18
多继承(利用对象冒充可以实现多继承)
function FatherA(name) {
this.name = name ;
this.getName = function () {
return this.name;
}
}
function FatherB(job) {
this.job = job;
this.getJob = function () {
return this.job;
}
}
function Son(name,job,age) {
this._newMethod = FatherA;
this._newMethod(name);
delete this._newMethod;
this._newMethod = FatherB;
this._newMethod(job);
delete this._newMethod;
this.age = age;
this.getAge = function () {
return this.age;
}
}
var fatherA = new FatherA("Tom");
var fatherB = new FatherB("Engineer");
var son = new Son("Jack","Programmer",18);
console.log(fatherA.getName());//Tom
console.log(fatherB.getJob());//Engineer
console.log(son.getName());//Jack//继承父类FatherA的getName()方法
console.log(son.getJob());//Programmer//继承父类FatherB的getJob()方法
console.log(son.getAge());//18
call()方法
function Father(name) {
this.name = name ;
this.getName = function () {
return this.name;
}
}
function Son(name,job,age) {
Father.call(this,name);
this.age = age;
this.getAge = function () {
return this.age;
}
}
var father = new Father("Tom");
var son = new Son("Jack","Programmer",18);
console.log(father.getName());//Tom
console.log(son.getName());//Jack//继承父类getName()方法
console.log(son.getAge());//18
多继承(利用call()方法实现多继承)
function FatherA(name) {
this.name = name ;
this.getName = function () {
return this.name;
}
}
function FatherB(job) {
this.job = job;
this.getJob = function () {
return this.job;
}
}
function Son(name,job,age) {
FatherA.call(this,name);
FatherB.call(this,job);
this.age = age;
this.getAge = function () {
return this.age;
}
}
var fatherA = new FatherA("Tom");
var fatherB = new FatherB("Engineer");
var son = new Son("Jack","Programmer",18);
console.log(fatherA.getName());//Tom
console.log(fatherB.getJob());//Engineer
console.log(son.getName());//Jack//继承父类FatherA的getName()方法
console.log(son.getJob());//Programmer//继承父类FatherB的getJob()方法
console.log(son.getAge());//18
apply()方法
function Father(name) {
this.name = name ;
this.getName = function () {
return this.name;
}
}
function Son(name,job,age) {
Father.apply(this,new Array(name));
this.age = age;
this.getAge = function () {
return this.age;
}
}
var father = new Father("Tom");
var son = new Son("Jack","Programmer",18);
console.log(father.getName());//Tom
console.log(son.getName());//Jack//继承父类getName()方法
console.log(son.getAge());//18
多继承(利用apply()方法实现多继承)
function FatherA(name) {
this.name = name ;
this.getName = function () {
return this.name;
}
}
function FatherB(job) {
this.job = job;
this.getJob = function () {
return this.job;
}
}
function Son(name,job,age) {
FatherA.apply(this,new Array(name));
FatherB.apply(this,new Array(job));
this.age = age;
this.getAge = function () {
return this.age;
}
}
var fatherA = new FatherA("Tom");
var fatherB = new FatherB("Engineer");
var son = new Son("Jack","Programmer",18);
console.log(fatherA.getName());//Tom
console.log(fatherB.getJob());//Engineer
console.log(son.getName());//Jack//继承父类FatherA的getName()方法
console.log(son.getJob());//Programmer//继承父类FatherB的getJob()方法
console.log(son.getAge());//18
原型链方法
function Father() {
}
Father.prototype.name = "Tom";
Father.prototype.getName = function () {
return this.name;
};
function Son() {
}
Son.prototype = new Father();
Son.prototype.age = 18;
Son.prototype.getAge = function () {
return this.age;
};
var father = new Father();
var son = new Son();
console.log(father.getName());//Tom
console.log(son.getName());//Tom//继承父类FatherA的getName()方法
console.log(son.getAge());//18
混合方式(call()+原型链)
function Father(name) {
this.name = name;
}
Father.prototype.getName = function () {
return this.name;
};
function Son(name,age) {
Father.call(this,name);
this.age = age;
}
Son.prototype = new Father();
Son.prototype.getAge = function () {
return this.age;
};
var father = new Father("Tom");
var son = new Son("Jack",18);
console.log(father.getName());//Tom
console.log(son.getName());//Jack//继承父类Father的getName()方法
console.log(son.getAge());//18
多态机制实现
function Person(name) {
this.name = name;
if (typeof this.getName !== "function"){
Person.prototype.getName = function () {
return this.name;
}
}
if (typeof this.toEat !== "function"){
Person.prototype.toEat = function (animal) {
console.log( this.getName() + "说去吃饭:");
animal.eat();
}
}
}
function Animal(name) {
this.name = name;
if (typeof this.getName !== "function"){
Animal.prototype.getName = function () {
return this.name;
}
}
}
function Cat(name) {
Animal.call(this,name);
if (typeof this.eat !== "function"){
Cat.prototype.eat = function () {
console.log(this.getName() + "吃鱼");
}
}
}
Cat.prototype = new Animal();
function Dog(name) {
Animal.call(this,name);
if (typeof this.eat !== "function"){
Dog.prototype.eat = function () {
console.log(this.getName() + "啃骨头");
}
}
}
Dog.prototype = new Animal();
var person = new Person("Tom");
person.toEat(new Cat("cat"));//Tom说去吃饭:cat吃鱼
person.toEat(new Dog("dog"));//Tom说去吃饭:dog啃骨头
以上这篇老生常谈javascript的面向对象思想就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
# javascript面向对象
# javascript中的面向对象
# js中的面向对象入门
# js面向对象编程总结
# Javascript基础回顾之(三) js面向对象
# JavaScript面向对象分层思维全面解析
# 多个
# 英语
# 可通过
# 值为
# 面向对象
# 不太
# 给大家
# 不高
# 可以使用
# 设置为
# 上讲
# 默认为
# 都是
# 吃鱼
# 多态
# 在这个
# 老生常谈
# 三大
# 将其
# 希望能
相关文章:
php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】
如何快速搭建FTP站点实现文件共享?
如何解决ASP生成WAP建站中文乱码问题?
建站之星如何通过成品分离优化网站效率?
网站制作壁纸教程视频,电脑壁纸网站?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
如何快速登录WAP自助建站平台?
如何选择适合PHP云建站的开源框架?
如何选择CMS系统实现快速建站与SEO优化?
已有域名能否直接搭建网站?
宁波自助建站系统如何快速打造专业企业网站?
如何通过FTP空间快速搭建安全高效网站?
高端智能建站公司优选:品牌定制与SEO优化一站式服务
香港服务器建站指南:免备案优势与SEO优化技巧全解析
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
如何打造高效商业网站?建站目的决定转化率
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
英语简历制作免费网站推荐,如何将简历翻译成英文?
太平洋网站制作公司,网络用语太平洋是什么意思?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
建站主机核心功能解析:服务器选择与网站搭建流程指南
赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?
如何用景安虚拟主机手机版绑定域名建站?
如何通过PHP快速构建高效问答网站功能?
建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析
成都网站制作报价公司,成都工业用气开户费用?
建站之星好吗?新手能否轻松上手建站?
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
如何在万网自助建站中设置域名及备案?
广州美橙建站如何快速搭建多端合一网站?
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
官网网站制作腾讯审核要多久,联想路由器newifi官网
seo网站制作优化,网站SEO优化步骤有哪些?
c# Task.ConfigureAwait(true) 在什么场景下是必须的
网站制作新手教程,新手建设一个网站需要注意些什么?
如何制作网站标识牌,动态网站如何制作(教程)?
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
行程制作网站有哪些,第三方机票电子行程单怎么开?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
网站专业制作公司有哪些,做一个公司网站要多少钱?
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
娃派WAP自助建站:免费模板+移动优化,快速打造专业网站
如何选择高效便捷的WAP商城建站系统?
c++怎么用jemalloc c++替换默认内存分配器【性能】
如何通过宝塔面板实现本地网站访问?
建站之星代理商如何保障技术支持与售后服务?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
建站之星代理平台如何选择最佳方案?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
*请认真填写需求信息,我们会在24小时内与您取得联系。