针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内。写这个主要是当个笔记加总结

存在的问题请大家多多指正!

6.1理解对象

创建对象的两个方法(暂时)

 //第一种,通过创建一个Object类型的实例,然后为他添加属性和方法
var person = new Object()
person.name = 'laotie'
person.sayName = function(){
alert(this.name)
}
//第二种简化版
var person = {
name: 'laotie',
sayName: {
alert(this.name)
}
}

6.1.1 类型属性

1.数据属性

JS不能访问的数据属性

  • Configurable 能不能用delete删除 默认true
  • Enumerable 能否通过for-in循环返回属性 默认true
  • Writable 能否修改属性 默认true
  • Value 就是这个属性的属性值 默认undefined

Object.defineProperty()接收三个参数:属性所在的对象,属性的名字和一个描述符对象 描述符对象必须是上面那四个

var person = {}
Object.defineProperty(person, 'name', {\
//我设置了,其中person的属性name,所以name这个属性他就动不了了
writable: false,
value: 'laotie'
}) alert(person.name) //'laotie'
person.name = '666'
alert(person.name) //'laotie'

如果用Object创建的属性一般configurable,enumerable,writable的默认值都是false,如果不用他创建的话就没有限制。

总之这个东西没什么太大实际用处,帮助理解吧

2.访问器属性
  • Configurable, enumerable 跟上面的差不多
  • Get 在读取属性时调用的函数
  • Set 在写入时调用的属性 get,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
alert(book.edition) //

老方法不介绍了,是直接在对象后面调用__defineGetter__和__defineSetter__,参数里面第一个是属性,第二个穿进去个处理函数

6.1.2定义多个属性

ES5加了个牛逼的Object.defineProperties()方法
第一个参数里放要修改属性的对象 ,第二个加个代码块里面方参数

var book = {}
Object.defineProperties(book,{
_year: {
writable: true,
value:2004
},
edition: {
writable: true,
value: 1
},
set:function(newValue){
if(newValue > 2004){
this._year = newValue
this.edition += newValue - 2004
}
}
})

6.1.3读取属性的特性

Object.getOwnPropertyDescriptor()

var descript = Object.getOwnPropertyDescriptor(book, '_year')
alert(descript.value) //
alert(descript.configurable) //false

6.2创建对象

6.2.1工厂模式

fucntion createPerson(name, age, job){
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function(){
alert(this.name)
} return o
} var person1 = creatPerson('laotie', 26, 'meiyou')

没法解决你这个对象什么类型的,因为对象在里面创建的,很迷

6.2.2构造函数模式

    //构造函数首字母大写 Person
function Person(name, age, job){
this.name = name
this.age = age
this.job = job
this.sayName = function(){
alert(this.name)
}
}
//有个new
var person1 = new Person('laotie', 26, 'meiyou')

instanceof验证是谁的实例

person1 instanceof Object //true
person1 instanceof Person //true
  • 如果不按套路用构造函数可以不用new 然后也可以没有变量接着
Person('laotie', 25, '666') //添加对象到window
window.sayName() //‘laotie’

构造函数中的方法在不停的声明function实例,每一个同名function通过新对象的创建都在不停地复制着等于this.sayName = new Function('alert(this.name)')

可以这样改

    //构造函数首字母大写 Person
function Person(name, age, job){
this.name = name
this.age = age
this.job = job
this.sayName = sayName
} function sayName(){
alert(this.name)
}

但是这样构建函数的话没有封装性可言,所以要用原型模式

6.2.3原型模式

每个函数都有一个prototype属性指向原型对象

//标准的原型模式函数是没有参数的
function Person(){} Person.prototype.name = 'laotie'
Person.prototype.age = 29
Person.prototype.job = '666'
Person.prototype.sayName = function(){
alert(this.name)
}

缺点:新建的所有对象所有属性都共享,没有传参

只要创建一个新函数, 那他就有一个原型的属性(prototype这个属性),这个属性指向他的原型对象,原型对象自动获得一个constructor属性(叫构造函数的属性),这个属性指向prototype属性所在的函数,新建的实例函数里都会有一个不可见的[[Prototype]]的属性(这个对象在火狐safari和chrome里可以看见,叫__proto__)指向原型对象

原型模式函数创建的对象可以再给属性赋值,赋的值可以掩盖原型对象中的值
delete你自己赋的值之后原型对象里的值还可以用

person1.hasOwnProperty('name') //可以看有无自己赋值的属性,有事true ,没有false
'name' in person1 //不管是自己的属性还是原型对象里的属性,只要有值就是true

简单点的设置prototype

function Person(){}
Person.prototype = {
//一般加上constructor: Person 要不然构造函数就跑到Object了
constructor: Person
name:'laotie',
sayName: function(){
alert(this.name)
}
}
新建对象是一定要在构造的后面哈,在前面建对象的话会断开和新建的原型对象的链接
function Person(){}
var person1 = new Person()
//相当于重新设置了Person的原型对象,现在的原型对象和person不是同一个了,所以person1中没有sayName这个函数
Person.prototype = {
constructor: Person
name:'laotie',
sayName: function(){
alert(this.name)
}
}
person1.sayName() //error

有个很大的毛病,就是原型模式函数不能自己传参,所以无论新建多少对象都是一个德行,没有属于自己的属性

6.2.4 把构造函数模式和原型模式组合一波

构造的定义不一样的属性,而原型模式构造一样的属性

function Person(name,age,job){
this.name = name
this.age = age
this.job = job
} Person.prototype = {
constructor: Person,
sayName: function(){
alert(this.name)
}
}

6.3继承

6.3.1原型链

原型模式构造函数:

  • 每个构造函数都会都会有一个原型对象,原型对象contrustor指向构造函数,实例对象[[prototype]]属性指向原型对象。

原型链就是把superType的实例对象给subType构造函数当原型。

还跟原型构造函数要注意的一样,就是在新建实力之后更改构造函数的原型,要不然就会断绝实例对象和新原型对象之间的联系

  • function SuperType(){
    this.property = true
    } SuperType.prototype.getSuperValue = function(){
    return this.property
    } function SubType(){
    this.subproperty = false
    } SubType.prototype = new SuperType() SubType.prototype.getSubValue = function(){
    return this.subproperty
    } var instance = new SubType() alert(instance.getSuperValue) //true

    原型模式参数传递不方便,所以菜的一批,所以借用构造函数

6.3.2 借用构造函数

就是在SubType里call或者apply一个SuperType,相当于在SubType调用了SuperType里的所有东西,所以就顺理成章的继承过来了

function SuperType(){
this.color = ['red', 'blue']
} function SubType(){
SuperType.call(this)
} var instance1 = new SubType()
instance1.colors.push('black')
alert(instance1.colors) //red,blue,black var instance2 = new SubType()
alert(instance.colors) //red,blue

与原型的不同就是可以传参数,然后用call的第二个后面或者apply的第二个函数赋值

但是问题是方法都在构造函数里,函数没法复用,所以就用组合式的比较吊,可以传参,可以函数复用

6.3.4 组合式继承

就是上面说的,用借用构造函数传参和设定基本属性,用原型链来做方法的复用

function SuperType(name) {
this.name = name
this.colors = ['red', 'blue']
} SuperType.prototype.sayName = function() {
alert(this.name)
} function Subtype(name, age) {
//第二处这里在call的时候又引入了name 和color属性。所以重复了,这也是组合继承的缺点
SuperType.call(this, name)
this.age = age
}
//第一处在设置原型对象时候在原型对象中 有name 和color属性了,看上面⤴️
Subtype.prototype = new SuperType()
Subtype.prototype.constructor = SubType
Subtype.prototype.sayAge = function (){
alert(this.age)
}

这样的好处是可以传入参数可以有自己的属性,然后又可以有共同的函数

6.3.4 原型式继承

Object.creat()这个方法,可以放一个或者两个参数,一个参数的时候是第一个是一个对象
第二个函数是可以附加一些属性,通过{name:'laotie'}这样的直接加进去

原理类似下面

function object(o){
function F(){}
F.prototype = o
return new F()
}

其实就是讲一个对象丰富了加了一些属性,然后再返回一个实例对象。有一个弊端,没有creat之前的内容和属性始终会共享。

6.3.5 寄生式继承

这个书上也没有仔细讲,给我感觉就是传进来一个对象,然后通过内部加强一些内容再返还出去

function creatAnother(original){
var clone = object(original)
clone.sayhi = funciton(){
alert('hi')
}
return clone
}

6.3.6 寄生组合式继承

尼古拉斯挑了个原型链继承的和借用继承的毛病,就是里面的参数会重复的建,占用内存,所以为了优化,就找了个寄生组合继承,给我感觉像是借用加上原型式(不是原型链继承模式是原型式)模式

function inheritPrototype(subType,SuperType){
var prototype = object(SuperType.prototype)
prototype.constructor = subType
subtype.prototype = prototype
}

这个不就是原型式继承吗?为啥要带上寄生式,感觉没寄生式啥事。
然后剩下的用借用就行了

完整代码:

function SuperType(name){
this.name = name
this.colors = ['red','blue']
} SuperType.prototype.sayName = function(){
alert(this.name)
} function SubType(name,age){
SuperType.call(this,name)
this.age = age
} inheritPrototype(subType,SuperType) SubType.prototype.sayAge = function(){
alert(this.age)
}

javascript 对象的创建与继承模式的更多相关文章

  1. JavaScript 对象的创建和对6种继承模式的理解和遐想

      JS中总共有六种继承模式,包括原型链.借用构造函数.组合继承.原型式继承寄生式继承和寄生组合式继承.为了便于理解记忆,我遐想了一个过程,对6中模式进行了简单的阐述. 很长的一个故事,姑且起个名字叫 ...

  2. JavaScript对象的创建

    原文 简书原文:https://www.jianshu.com/p/6cb1e7b7e379 大纲 前言 1.简单方式创建对象的方法 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对 ...

  3. JavaScript 对象的创建和操作

    <script>         // 对象是属性的无序集合,每个属性都是一个名/值对. 属性名称是一个字符串.         // 对象种类         // 内置对象(nativ ...

  4. JavaScript对象的创建之使用json格式定义

    json: javascript simple object notation. json就是js的对象,但是它省去了xml中的标签,而是通过{}来完成对象的说明. 定义对象 var person = ...

  5. Greenplum+Hadoop学习笔记-14-定义数据库对象之创建与管理模式

    6.3.创建与管理模式 概述:DB内组织对象的一种逻辑结构.一个DB内能够有多个模式.在未指定模式时默认放置在public中.能够通过"\dn"方式查看数据库中现有模式: test ...

  6. Greenplum中定义数据库对象之创建与管理模式

    创建与管理模式 概述:DB内组织对象的一种逻辑结构.一个DB内能够有多个模式.在未指定模式时默认放置在public中.能够通过"\dn"方式查看数据库中现有模式. testdw=# ...

  7. JavaScript对象的创建之基于构造方法+原型方式

    为了解决原型所带来的问题,此处需要通过组合构造方法和原型来实现对象的创建,将属性在构造方法中定义,将方法在原型中定义.这种有效集合了两者的优点,是目前最为常用的一种方式. function Perso ...

  8. Javascript对象的创建模式 -- 深入了解Javascript

    /* 一.模式1:命名空间(namespace) 优点:减少全局命名所需的数量,避免命名冲突或过度 */ // 更简洁的方式 var MYAPP = MYAPP || {}; //定义通用方法 MYA ...

  9. 菜鸟快飞之JavaScript对象、原型、继承(三)

    正文之前需要声明的一点是,菜鸟系列博文全是基于ES5的,不考虑ES6甚至更高版本. 继承 由于我个人不是学计算机的,所以对于很多东西只是知其然,不知其所以然.就像这个继承,刚开始学JavaScript ...

随机推荐

  1. int数据类型的最大数

    /* 32位系统 */ #include <stdio.h> int main() { , b = ; ) { ; } printf(); ; do { n = n / ; b++; } ...

  2. git的使用(二)

    GITHUB 简介 github可以是全世界最大的同性交友网站,其实就是和百度云一个性质. gitHub于2008年4月10日正式上线,除了git代码仓库托管及基本的 Web管理界面以外,还提供了订阅 ...

  3. 使用jmeter进行压力测试及如何添加负载机

    Jmeter是一款简单灵活且强大的性能测试工具,同时也可以做接口测试. 由于初识jmeter,今天来记录一下如何对一个web进行一个简单的压力测试. 1.首先在测试计划里面添加一个线程组,然后再其下面 ...

  4. 201871010102-常龙龙《面向对象程序设计(java)》第八周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  5. 201871010121-王方-《面向对象程序设计java》第十六周实验总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  6. 微信小程序 - 事件 | 传递 | 冒泡

    事件 常见的事件有: 类型 触发条件 最低版本 touchstart 手指触摸动作开始   touchmove 手指触摸后移动   touchcancel 手指触摸动作被打断,如来电提醒,弹窗   t ...

  7. USACO Apple Delivery

    洛谷 P3003 [USACO10DEC]苹果交货Apple Delivery 洛谷传送门 JDOJ 2717: USACO 2010 Dec Silver 1.Apple Delivery JDOJ ...

  8. Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4) 题解

    Happy Birthday, Polycarp! Make Them Odd As Simple as One and Two Let's Play the Words? Two Fairs Bea ...

  9. 0x00 Wechall writeup

    目录 0x00 Wechall writeup Training: Get Sourced Training: ASCII Encodings: URL Training: Stegano I Tra ...

  10. 【day03】php

    一.类型判别函数库 1.安装:类型判别函数库是PHPCORE的组成部分,不用安装 2.  (1)is_integer|is_int|is_long     描述:  检测变量是否是整数     格式: ...