javaScript 的面向对象程序
理解对象
属性类型
数据属性(数据属性包含一个数据值的位置,这个位置可以读取和写入值,数据属性有4描述)
[Configurable]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性的特性,或者能否把属性修改为访问器属性,像前面例子中
那样直接在对象上定义的属性,他们的这个特性默认为true.
var person = {};
Object.defineProperty(person,'name',{
configurable:false,
value:"Nicholas"
});
alert(person.name); // "Nicholas"
delete person.name;
alert(person.name); //"Nicholas"
[Enumerable]: 表示能否通过for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这特性默认值为true.
[Writable]: 表示能否修改属性的值,像前面例子中那样直接子对象上定义的属性,它们的这个属性默认值为true.
var person = {};
Object.defineProperty(person,'name',{
writable:false,
value:"Nicholas"
});
alert(person.name); // "Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"
[Value]: 包含这个属性的数值,读取属性值的时候,从这个位置读; 写入属性值的时候把新值保存在这个位置,这个属性的默认值为undefined;
访问器属性 (访问器属性不能直接定义,必须使用Object.defineProperty() 来定义)
[Configurable]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性的特性,或者能否把属性修改为访问器属性,像前面例子中
那样直接在对象上定义的属性,他们的这个特性默认为true.
[Enumerable]: 表示能否通过for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这特性默认值为true.
[Get]: 在读取属性时调用的函数。默认值为undefined。
[Set]: 在写入属性时调用的函数。默认值为undefined。
var book={
_year:2004,
edition:1
}
Object.defineProperty(book,"year",{
get:function(){
return this._year;
},
set:function(newValue){
if(newValue > 2004){
this._year = newValue;
this.edition += newValue -2004;
}
}
})
book.year = 2005;
console.log(book.edition) // 2
var obj = {
_x:"obj._x",
_y:"obj._y",
_z:"Obj._z"
}
Object.defineProperty(obj,"x",{ // x属性,只读不写
get:function(){
return this._x;
}
});
console.log(obj.x); // "obj._x"
obj.x = "Rewrite x"; // 尝试修改x属性
console.log(obj.x); // "obj.x" 写入失败
Object.defineProperty(obj,"y",{ // y属性,只写不能读
set:function (newValue){
this._y = newValue;
}
});
console.log(obj.y); // "undefined" 读取失败
obj.y = "Rewrite obj.y"; // 尝试修改属性
console.log(obj._y); // "Rewrite obj.y" 可以写入
Object.defineProperty(obj,"z",{
get:function(){
return this._z;
},
set:function (newValue){
this._z = newValue;
}
});
console.log(obj.z); //"obj.z"
obj.z = "Rewrite obj.z"; // 修改z 属性
console.log(obj._z); // "Rewrite obj.z"
创建访问器属性一般使用两个标准方法:_defineGetter_()和_defineSetter_()。
var book = {
_year;2004,
edition:1
};
// 定义访问器的旧有方法
book.__defineGetter__("year",function(){
return this._year;
});
book.__defineSetter__("year",function(newValue){
if(newValue > 2004){
this._year = newValue;
this.edition += newValue -2004;
}
});
book.year = 2005;
console.log(book.edition); // 2
定义多个属性 对象定义多个属性的可能性很大,利用Object.defineProperties() 方法可以通过描述一次定义多个属性。
var book = {};
Object.defineProperties(book,{
_year:{
value;2004
},
edititon:{
value;1
},
year:{
get:function(){
return this._year;
},
set:function(newValue){
if(newValue > 2004{
this._year = newValue;
this.edition += newValue -2004;
}
}
}
})
读取属性的特性 Object.getOwnPropertyDescriptor() 方法可以取得给定属性的描述符,这个方法接收两个参数 属性所在的对象和要读取其描述的属性
返回是一个对象: 如果是访问器属性,这个对象属性有 configurable,enumerable,get 和set;
如果是数据属性 ,这个的对象的属性有 configurable,enumerable,writable和value。
var book = {};
Object.defineProperties(book,{
_year:{
value;2004
},
edition:{
value:1
},
year:{
get:function(){
return this._year;
},
set:funtion(newValue){
if(newValue > 2004){
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
})
var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
console.log(descriptor.value); // 2004
console.log(descriptor.configurable); //false
console.log(descriptor.get); // undefined
var descriptor = Object.getOwnPropertyDescriptor(book,"year");
console.log(descriptor.value); // undefined
console.log(descriptor.enumerable) // false
console.log(typeof descriptor.get) // function
创建对象
工厂模式
function createPerson(name,age,job){
var o = new Object();
o.name = neame;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name)
};
return o;
}
var person1 = createPerson("Nicholas",29,"Software Engineer");
var person2 = createPerson("Greg",27,"Doctor")
// 函数 createPerson() 能够根据接受的参数来构建一个包含所有必要信息的person对象。
构造函数模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
}
var person1 = new Person("Nicholas",29,"Software Enginerer");
var person 2 = new Person("Greg",27,"Doctor");
}
要创建Person 的实例,必须使用new 操作符,以这种方式调构造函数实际上会经历以下4个步骤
1.创建一个行对象。
2.构造函数的作用域赋给新对象(因此this 就指向了这个新对象)
3.执行构造函数中的代码(为这个新对象添加属性)
4.返回新对象。
原型模式
function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.protoype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); // "Nicholas"
var person2 = new Person();
person2.sayName();
alert(person1.sayName == person2.sayName); // true
在实例中无法访问到[[Prototype]],可以通过isPrototypeOf() 方法来确定对象直接是否存在这种关系。
console.log(Person.prototype.isPrototypeOf(person1)); // true console.log(Person.prototype.isProtoypeOf(Person2));// true
Object.getPrototypeOf(),在所有支持的实现中,这个方法返回[[Protoype]]的值。
console.log(Object.getPrototypeOf(person1) == Person.prototype); // true console.log(Object.getPrototypeOf(person1).name); // "Nicholas"
使用delete 操作符则可以完全删除实例属性,可以重新访问原型中的属性。
function Person(){}
Person.prototype.name = 'Nicholas';
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.protooype.sayName = function(){
console.log(this.name)
}
var person1 = new Person();
var person2 = new Person();
person1.name = "Greg";
console.log(person1.name); // "Greg" 来自实例
console.log(person2.name); // "Nicholas" 来自原型
delete person1.name;
console.log(person1.name); // “Nicholas” 来自原型
Object.keys() 方法 接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。
function Person(){}
Person.prototype.name = "Nicholas"
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer"
Person.prototype.sayName = function(){
console.log(this.name);
}
var keys =Object.keys(Person.ptototype);
console.log(keys) // "name,age,job,sayName"
var p1 = new Person();
pl.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
console.log(p1keys); //"name,age"
无论是否可枚举,都可以使用Object.getOwnPropertyNames();
var keys = Object.getOwnPertyNames(Person.protoype);
console.log(keys) // “constructor,name,age,job,sayName”
对象字面量来重写原型
function(){}
Person.prototype = {
name:"Nicholas",
age:29,
job:"Software Engineer",
sayName:function(){
console.log(this.name);
}
}
重设构造函数
Object.defineProperty(Person.prototype."constructor",{
enumerable:false,
value:Person
})
实例中的指针仅指向原型,而不执行构造函数
function Person(){}
var friend = new Person();
Person.prototype = {
constructor:Person,
name:"Nicholas",
age:29,
job:"Software",
sayName:function(){
console.log(this.name)
}
};
friend.sayName(); // error
组合使用构造函数模式和原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby","Court"];
}
Person.protoype = {
constructor :Person,
sayName:function(){
console.log(this.name)
}
}
var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Greg",27,"Doctor")
person1.friends.push("Van");
console.log(person1.friends); // "Shelby,Count,Van"
console.log(person2.friends); //"Shelby,Count"
console.log(person1.friends === person2.frends); // false
console.log(person1.sayName === person2.sayName); // true
动态原型模式
funciton Person(name,age,job){
// 属性
this.name = name;
this.age = age;
this.job = job;
// 方法
if(typeof this.sayName != "function"){
Person.prototype.sayName = function(){
console.log(this.name)
}
}
}
var friend = new Person("Nicholas",29,"Softeare Engineer");
friend.sayName();
寄生构造函数模式
function Person(){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name)
}
return o;
}
var friend = new Person('Nicholas',29,"Software Engineer");
friend.sayName(); //"Nicholas”
稳妥构造函数模式
function Person(name,age,job){
// 创建要返回的对象
var o = new Object();
// 可以在这里定义私有变量和函数
// 添加方法
o.sayName = function(){
console.log(name)
}
// 返回对象
return o;
}
var friend = Person("Nicholas",29,"Software Engineer");
friend.sayName(); // "Nicholas"
继承 (ECMAScript 只支持实现继承,而且实现继承主要依靠)
原型链
function SuperType(){
this.property = true;
}
SuperType.protoype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
// 继承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subproperty;
};
var instance = new SubType();
console.log(instance.getSuperValue()) // true
// 在调用 instance.getSuperValue() 会经历三个搜索步骤1.搜索实例2.搜索SubType.prototype;3.搜索SuperType.ptototype ,最后一步才会找到方法
1.所有函数的默认原型都是Object的实例,默认原型会包含一个内部指针,指向 Object.prototype 这也是所有自定义类型都会继承 toString() ,valueOf() 等默认方法的根本原因。
2.确定原型和实例的关系 (第一种方式是使用instanceof, 第二个方式是使用isPrototypeOf())
console.log(instance instanceof Object); // true
console.log(instance instanceof SuperType) // true
console.log(instance instanceof SuperType) //true
console.log(Object.prototype.isPrototypeOf(instance)); // true
console.log(Object.prototype.isPrototypeOf(instance)); // true
console.log(Object.prototype.isPrototypeOf(instance)); // true
3.有时候需要重新超类中的某个方法,给原型添加方法一定要房子替换原型语句之后。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
this.subproerty = false;
}
// 继承了SuperType
SubType.prototype = new SuperType();
// 添加新方法
SubType.prototype.getSubValue = function(){
return this.subproperty;
};
// 重写超类型中的方法,
SubType.prototype.getSuperValue = function(){
return false;
}
var instance = new SubType();
console.log(instance.getSuperValue()); // false
4.原型链的问题
function SuPerType(){
this.colors = ['red','blue',"green"]
}
function SubType(){}
// 继承了 SuperType
var instance1 = new SuperType();
instancel.colors.push("black");
console.log(instance1.colors);
var instance2 = new SubType();
console.log(instance2.colors); //"red,blue,green,black"
var instance2 = new SubType();
console.log(instance2.colors); // "red,blue,green,black"
借用构造函数 (函数只不过是在特定环境中执行代码的对象,因此通过使用apply() 和 call() 方法也可以在将来新创建的对象上执行构造函数)
function SuperType(){
this.colors = ["red","blue","grren"];
}
function SubType(){
// 继承了SuperType
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
conole.log(insstance1.colors); // 'red,blue,green,black'
var instance2 = new SubType();
console.log(instance2.colors); //"red,blue,green"
组合继承(是将原型链和借用构造函数组合到一起)
function SuperType(name){
this.name = name;
this.colors = ["red","blue","green"]
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
// 继承属性
SuperType.call(this,name);
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
console.log(this.age);
}
var instancel = new SubType("Nicolas",29);
instancel.colors.push("black")
console.log(instancel.colors); // "red,blue,green,black"
instancel.sayName(); // "Nicholas"
instancel.sayAge(); //29
var instnce2 = new SubType("Greg",27);
console.log(instnce2.colors); // "red,blue,green"
instance2.sayName(); // "Greg"
instance2.sayAge(); // 27
原型式继承
var person = {
name:"Nicholas",
friends:["Shelby","Court","Van"]
}
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends); // "Shelby,Court,Van,Rob,Barbie"
var person = {
name:"Nicholas",
friends:["Shelby","Court","Van"]
}
var anotherPerson = Object.create(person,{
name:{
value:"Greg"
}
})
console.log(anotherPerson.name); // "Greg"
寄生式继承
function createAnother(original){
var clone = Object(original); // 通过调用函数创建一个新对象
clone.sayHi = function(){ // 以某种方式来增强增对象
console.log("hi")
}
return clone; // 返回这个对象
}
var person = {
name:"Nicholas",
friends:["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); // "hi"
寄生组合式继承
function SuperType(name){
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototypes.sayName = function(){
SuperType.call(this,name); // 第二次调用SuperType
this.age = age;
}
SubType.prototype = new SuperType(); // 第一次调用 SuperType
SubType.prototype.constructor = SubType;
subType.prototype.sayAge = function(){
console.log(this.age)
}
javaScript 的面向对象程序的更多相关文章
- JavaScript的面向对象编程(OOP)(一)——类
在学习JavaScript面向对象的编程之前,需要知道,并了解面向对象的一些基本的常识.初学者中大多数都以为面向对象中,面向对象的编程是很重要和占据很大一部分精力.笔者在之前也是认为OOP是面向对象的 ...
- javascript进阶——面向对象特性
面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...
- javascript 的面向对象特性参考
最近在看用javascript+css实现rich client.javascript 也是一个蛮有意思的语言.特别是其面向对象的实现和其他“标准”的OO launguage有很大的不同.但是,都是动 ...
- JavaScript中国象棋程序(0) - 前言
“JavaScript中国象棋程序” 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.希望通过这个系列,我们对博弈程序的算法有一定的了解.同时,我们也将构建出一个不错的中国象棋程序 ...
- JavaScript中国象棋程序(1) - 界面设计
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第1节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(2) - 校验棋子走法
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第2节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(3) - 电脑自动走棋
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第3节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(4) - 极大极小搜索算法
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第4节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(5) - Alpha-Beta搜索
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第5节. 这一系列共有9个部分: 0.JavaScript中国象 ...
- JavaScript中国象棋程序(6) - 克服水平线效应、检查重复局面
"JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第6节. 这一系列共有9个部分: 0.JavaScript中国象 ...
随机推荐
- 【YashanDB数据库】VMware虚拟机使用默认安装,在掉电之后数据库无法启动
问题现象 客户使用VMware虚拟机使用默认安装,部署YashanDB个人版,在掉电之后无法启动 操作系统: Virtualization: VMware Operating System: Cent ...
- angular 知识
看完以下内容应该就可以上手Angular了 https://angular.io/start Udemy - Complete Angular 14 Course - Learn Frontend D ...
- Coursera, Big Data 5, Graph Analytics for Big Data, Week 5
Computing Platforms for Graph Analytics programming models for Graphs Giraph and GraphX 其中讲 GraphX 的 ...
- CSS – Reset CSS / Base CSS
前言 许多 element tag 都有自带的 style. 比如 h1 默认 font-size 是 2 em anchor 默认颜色是 blue 大部分默认 style 并不会是开发人员期望的效果 ...
- Let's Encrypt Free SSL – Certify The Web
介绍 随着 Let's Encrypt 的普及. 现在为网站升级到 HTTPS 已经不需要付费了. Let's Encrypt 的 SSL 是免费的, 每 3 个月需要更新一次. 可以完全用 API ...
- HTML——基础标签
基础标签 图片.音频.视频标签 src:资源路径 1.绝对路径 2.相对路径 ./ 表示本级目录 (可以省略) ../ 表示上级目录 超链接标签 列表标签 表格标签 ...
- Adobe Pr 软件报错,此效果需要GPU加速
事件起因: 某同事使用PR软件报错,报错截图如下: 解决办法: 1.在pr菜单栏选择文件-项目设置-常规-视频渲染和回放-渲染程序,切换到Mercury Playback Engine GPU加速 ...
- 【赵渝强】使用二进制包部署Kubernetes集群
在一些企业的私有环境中可能无法连接外部的网络.如果要在这样的环境中部署Kubernetes集群,可以采集Kubernetes离线安装的方式进行部署.即:使用二进制安装包部署Kubernetes集群,采 ...
- pytorch中y.data.norm()的含义
import torch x = torch.randn(3, requires_grad=True) y = x*2 print(y.data.norm()) print(torch.sqrt(to ...
- 反射获取Exception的所有类
var test = "test"; $"{test} 喜喜".Dump(); // 反射 var types = Assembly .GetAssembly( ...