深入javascript之对象

OOP

前言

这是读书笔记第二篇,看完之后突然发现自己对js的内置的一些东西还是了解的不够全面,很多方法见都没见过,啥用都不知道,这是非常不可取的。码农好歹也得眼熟啊,晓都不晓得后面的学习还怎么进行下去。。。赶紧做笔记吧~文中如有错误不当不出,欢迎指出~

创建一个对象

var obj = {}  //字面量创建
var obj = new Object()  //构造函数创建

2种创建方式是完全一样的,一般书写我们都采用字面量。

复制对象

首先明确一点,借用红宝书一句话,对于对于js中的赋值传参等操作,传递的都是值,不关是基本类型还是引用类型,传递的都是值,只是引用类型传递的是一个内存地址的值。不同对象如果引用同一块内存地址,还是会相互影响的。对象就是引用类型,这里介绍2种简单的方法来复制对象,又能不相互影响。

//安全的json序列对象,只能复制键值对,不能复制函数

JSON.parse(JSON.stringify(obj))


//es6新增的内置方法复制对象


Object.assign({},obj1,obj2...)

对象属性的特性

一般我们看到的对象就是一对对键值对,其实内部并没有我们想象的这么简单。看以下代码:

var a = {
            a:2,
            fuc:function() {    
            console.log('xxx')
            }
        }
        
        //通过Object.getOwnPropertyDescriptors获取对象属性
        Object.getOwnPropertyDescriptors(a)
        a: {
        configurable: true  //可配置
        enumerable: true  //可枚举
        value: 2
        writable: true // 可写
        }
        .....
        

我们看到a属性除了一个值外,还有3个默认特性,继续看:

var myObject = {};

Object.defineProperty( myObject, "a", {
    value: 2,
    writable: false, // not writable! 
    configurable: true,
    enumerable: true
} );

myObject.a = 3;

myObject.a; // 2

通过Object.defineProperty定义了一个a属性,该属性不可写,结果上我们已经无法修改属性值。

var myObject = { 
    a:2
};

myObject.a; // 2

delete myObject.a; 
myObject.a; // undefined

Object.defineProperty( myObject, "a", {
    value: 2,
    writable: true, 
    configurable: false, 
    enumerable: true
} );

myObject.a; // 2 
myObject.a = 5; 
myObject.a; // 5


delete myObject.a; 
myObject.a; // 5

设置属性不可配置,我们看到我们无法再删除这个属性,但是仍然可以修改值。enumerable特性我们就比较熟悉了,for in循环枚举属性就是枚举可枚举的属性,如果我们设置为false ,这个属性就不会被枚举。

要注意有一个小小的例外:即便属性是configurable:false, 我们还是可以把writable的状态由true改为false,但是无法由false改为true。

自定义属性的set和get

var myObject = {
    // 给 a 定义一个getter
    get a() {
        return this._a_; 
    },

    // 给 a 定义一个setter
    set a(val) {
        this._a_ = val * 2;
    } 
};

myObject.a = 10 ;
myObject.a   //20

上面代码我们复写了a属性的获取和设置方法,没有赋值直接获取会返回undefined,通过这个可以使我们创造出一些有趣的东西,vue源码中我们就能看到很多实际的例子。

propertyIsEnumerable(..)会检查给定的属性名是否直接存在于对象中(而不是在原型链上)并且满足enumerable:true。

Object.keys(..)会返回一个数组,包含所有可枚举属性,Object.getOwnPropertyNames(..)会返回一个数组,包含所有属性,无论它们是否可枚举。

in和hasOwnProperty(..)的区别在于是否查找[[Prototype]]链,然而,Object.keys(..)和Object.getOwnPropertyNames(..)都只会查找对象直接包含的属性。

内置方法这里不再赘述,实时了解ecmascript的动态,掌握新的内容是非常必要的,我们可能永远用不到一些内置方法,但是我们确保得先知道它,不然在需要的时候可能会像无头苍蝇乱撞或者使用一些比较蠢的老方法。

面向对象编程

什么是面向对象编程?这个问题是我入坑时无法解惑的一个问题。但是随着业务的不断积累,这个问题会变得越来越清晰。

我们首先会介绍面向类的设计模式:实例化(instantiation)、继承(inheritance)和(相对)多态(polymorphism)。

类理论

类/继承描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法。

面向对象编程强调的是数据和操作数据的行为本质上是互相关联的(当然,不同的数据有不同的行为),因此好的设计就是把数据以及和它相关的行为打包(或者说封装)起来。这在正式的计算机科学中有时被称为数据结构。

举例来说,用来表示一个单词或者短语的一串字符通常被称为字符串。字符就是数据。但是你关心的往往不是数据是什么,而是可以对数据做什么,所以可以应用在这种数据上的行为(计算长度、添加数据、搜索,等等)都被设计成String类的方法。

所有字符串都是String类的一个实例,也就是说它是一个包裹,包含字符数据和我们可以应用在数据上的函数。

我们还可以使用类对数据结构进行分类,可以把任意数据结构看作范围更广的定义的一种特例。

我们来看一个常见的例子,“汽车”可以被看作“交通工具”的一种特例,后者是更广泛的类。

“在我们的软件中,对不同的交通工具重复定义“载人能力”是没有意义的。相反,我们只在Vehicle中定义一次,定义Car时,只要声明它继承(或者扩展)了Vehicle的这个基础定义就行。Car的定义就是对通用Vehicle定义的特殊化。

虽然Vehicle和Car会定义相同的方法,但是实例中的数据可能是不同的,比如每辆车独一无二的VIN(Vehicle Identification Number,车辆识别号码),等等。

这就是类、继承和实例化。

类的另一个核心概念是多态,这个概念是说父类的通用行为可以被子类用更特殊的行为重写。实际上,相对多态性允许我们从重写行为中引用基础行为。

'类'设计模式

你可能从来没把类作为设计模式来看待,讨论得最多的是面向对象设计模式,比如迭代器模式、观察者模式、工厂模式、单例模式,等等。从这个角度来说,我们似乎是在(低级)面向对象类的基础上实现了所有(高级)设计模式,似乎面向对象是优秀代码的基础。

考虑到尽可能容易理解。这里摘录了基本概念,这是一个抽象的东西,我们在撸码过程中可能不知不觉就已经在实践这种理念,但是没有看过这种概念的人可能会一下子说不出来。

这些概念实际上无法直接对应到JavaScript的对象机制,因此JavaScript开发者用一系列方法去模拟实现面相编程,比如混入,mixin。

这里说说在下对面相对象编程的理解 ,面向对象编程其实就是一类事物的抽象。比如 人,都会说话,走路,但是可能有的人说汉语,有的人说英语,对于这种广泛的抽象中又有非常多的特例,我们可以对其建模:

var Person = function(){ 
this.name = 'person',
this.age = '',
this.talk = function(){alert('talk')},
this.walk = function(){alert('wall')}
}
var p1 = new Person()
var p2 = new Person()

p1.name = 'xu'
p2.name = 'pp'
...

我们构造了一个person函数,通过person函数构造了2个人类实例,一个名字是xu一个名字是pp。。会说话,会走路。

ES6中的class语法

class Animal { 
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  speak() {
    console.log(this.name + ' barks.');
  }
}

var d = new Dog('Mitzie');
// 'Mitzie barks.'
d.speak();

es6的class语法糖让我们模拟面相编程变得更加规范,这里引用mdn的一个例子,更具体的建议可以自己找文章看,毕竟这是一个js一个非常重要的知识。

后记

要想完全搞懂一些概念,抽象的东西,其实并不是一天两天,一两篇文章就能做到的,我的建议是,理论,实践,理论,实践,一个螺旋上升的过程。感觉笔记内容不是很深入,毕竟是读书笔记和自己的一些理解看法,就当深入的程度不是那么深吧~

如果觉得本文对你有所帮助,就star一下吧~大传送之术! 我的博客Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容