javaScript系列 [02]-javaScript对象探析

题记:多年前,以非常偶然的方式关注了微信公众号“面向对象”`,本以为这个公众号主要以分享面向对象编程的干货为主,不料其乃实实在在的猿圈相亲平台。通过查看公开资料,发现该公众号俨然是在以自己的方式来帮助广大单身程序猿们通往一条真真正正的面向对象编程之路,相对而言,编程和语言特性这些破事又算得了什么呢,先“找到对象”似乎才是更高层面的话题。这篇文章,我们不谈如何"面向对象",只着力于JavaScript中对象特征、创建以及访问。
本文作为纯粹的技术文章,和“面向对象”公众号利益无关。

1.1 javaScript中对象简单说明

javaScript是一门基于弱类型、支持面向对象编程且基于原型继承的脚本语言

对象说明

在JavaScript语言中,对象是可变的键值对集合(或者称为属性的容器),通过对象我们可以方便的管理一组变量和函数。

用通俗的话来说,对象其实就是一堆变量和函数的集合。只是“定义”在对象中的变量,我们称为属性,“定义”在对象中的函数,我们称之为方法。

数据类型和对象

JavaScript中的数据类型可以分为基本数据类型和复杂数据类型
其中基本数据类型有:数字(number)、字符串(string)、布尔值(boolean)、undefined值和null。

复杂数据类型可以简单理解为对象类型。在JavaScript中,数组是对象、函数是对象、正则表达式是对象,对象自然也是对象,它们在使用typeof 运算符时得到的结果为object,即对象类型。

typeof对函数运算的结果为function,对null运算的结果为object,但这被认为是一个错误。

JavaScript语言中的对象是无类型的,对象可以拥有属性和方法,属性和方法都是以key-value的方式存储的。我们可以笼统的把方法和属性统一归类为属性(因为方法名其实和属性名没有任何本质的区别,属性和方法的分类方式只是对它们存储的内容进行人为区分),所以对象其实就是键值对的集合

对象通过引用来传递,它们永远不会被复制。

对象的检查

① 可以使用typeof来对对象类型进行简单的检查,但需要注意排除null的情况。

② 在开发中,经常会用到hasOwnProperty方法来过滤对象原型成员。

1.2 javaScript中对象的获取方式

JavaScript中对象的创建有多种方式,根据特定的应用场景,我们可以选择不同的更合适的方式来创建对象,简单可以归纳为以下情况:

① 字面量的方式创建对象
② 内置构造函数创建对象
③ 封装工厂函数创建对象
④ 定义构造函数创建对象
⑤ 调用系统方法创建对象

下面分别对上面列出的这些方式进行逐一介绍。

字面量的方式创建对象

基本写法

    var  bookObj = {
        name:"声名狼藉者的生活",
        price:42.00,
        author:"福柯",
        press:"北京大学出版社",
        read:function () {
            console.log("我的书名为:声名狼藉者的的生活,作者为福柯....");
        }
    };

上面的代码中通过字面量的方式创建了bookObj对象,该对象拥有name、price、author和press属性,还拥有read方法。

对象字面量提供了一种非常方便的创建新对象的表示方法,一个对象就是包围在{}中的N(N>=0)个键值对。对象字面量可以出现在任何允许表达式出现的地方。

内置构造函数创建对象

JavaScript中的内置构造函数主要有:

String
Number
Boolean
Date
Array
Function
Object
RegExp

注意:(String Number Boolean 是区别于string number boolean的基本包装类型)

基本写法

    var book = new Object();
    book.name = "声名狼藉者的生活";
    book.price = 42.00;
    book.author = "福柯";
    book.press = "北京大学出版社";
    book.read = function () {
        console.log("我的书名为:声名狼藉者的的生活,作者为福柯....");
    };

这种写法相对字面量创建方式而言不够简洁和直观,而且本身的代码复用性不好,不推荐。

工厂函数创建对象

工厂函数方式创建对象其本质是对内置构造函数创建对象的过程进行了封装,适用于大规模“批量生产”同类型的对象。
基本写法

    //提供工厂函数
    function createBookNew (name,price,author,press) {

        var book = new Object();
        book.name = name;
        book.price = price;
        book.author = author;
        book.press = press;
        book.read = function () {
            console.log("我的书名为:"+book.name+",作者为"+book.author+"....");
        };

        return book;
    }

    //使用工厂函数来创建对象
    var book1 = createBookNew("声名狼藉者的的生活","42.00","福柯","北京大学出版社");
    var book2 = createBookNew("人性的枷锁","49.00","毛姆","华东师范大学出版社");
    var book3 = createBookNew("悟空传","28.00","今何在","湖南文艺出版社");

    //打印对象的属性,调用对象的方法
    console.log(book1.name);
    console.log(book2.name);
    console.log(book3.name);

    book1.read();
    book2.read();
    book3.read();

总结工厂函数创建对象的实现过程

① 提供一个创建对象的函数(参数)
② 在函数内使用new 关键字和构造器创建对象
③ 设置对象的属性和方法
④ 返回加工过的对象

自定义构造函数创建对象

基本写法

        //提供构造函数
    function CreateBook (name,price,author,press) {

          //使用new调用该构造函数时,默认在内部会先创建Object类型的实例对象
          //并把该对象关联到当前构造函数的原型对象上,并把函数内的this绑定到该对象
          //通过this来给实例对象设置属性和方法
        this.name = name;
        this.price = price;
        this.author = author;
        this.press = press;
        this.read = function () {
            console.log("我的书名为:"+this.name+",作者为"+this.author+"....");
        };

            //默认总是把新创建的实例对象返回
    }

       //使用new + 函数名() 的方式来调用
    var bookObj = new CreateBook("声名狼藉者的的生活","42.00","福柯","北京大学出版社");

构造函数和普通函数没有本质区别,约定使用new调用的构造函数的首字母应该大写。
构造函数的作用在于完成对象的初始化,对象的创建等工作由new关键字完成,组合使用。

工厂函数和构造函数创建对象过程简单对象

① 函数的首字母大写(用于区别构造函数和普通函数)
② 创建对象的过程是由new关键字实现
③ 在构造函数内部会自动的创建新对象,并赋值给this指针
④ 自动返回创建出来的对象

构造函数调用方式的返回值

① 如果在构造函数中没有显示的return,则默认返回的是新创建出来的对象
② 如果在构造函数中显示的return,则依照具体的情况处理
❐ return 的是对象类型数据,则直接返回该对象
❐ return 的是null或其他基本数据类型数据,则返回新创建的对象(即this)

提示 : 在开发中我们通过把自定义构造函数和原型对象结合在一起使用,这样可以充分的利用JavaScript原型链继承的特性并解决方法的共享问题。下面给出基本的代码示例:

    //(1)提供Person构造函数
    function Person(name) {}
    //(2)替换Person默认的原型对象
    Person.prototype ={
        //修正构造器属性 Object --> Person
        constructor:Person,
        //提供实例对象的初始化方法
        init:function(name,age){
            this.name = name || "默认的姓名";
            this.age = age || 18;
        },
        //所有实例对象都需要访问的原型方法
        showName:function () {
            console.log(this.name);
        }
    };
    //(3)使用new来调用构造函数以创建实例对
    var p = new Person();
    //(4)调用init方法对实例对象进行初始化操作
    p.init("文顶顶",20);

使用Object.create方法创建对象

ES5提供了Object.create法来创建一个新对象,该方法在使用的时候会把传入的指定对象连接为新对象的原型对象。

语法
Object.create(proto, [propertiesObject])

参数说明
第一个参数proto:新创建对象的原型对象。
第二个参数propertiesObject:可选的参数,如果没有指定为 undefined,则表示要添加到新创建对象的可枚举属性信息,存放对象的属性描述符以及相应的属性名称。

如果传入的参数为null,则创建出来的空对象不会继承Object原型成员,没有基础方法。
如果传入的参数为Object.prototype,那么创建出来的对象等同于{}空对象。

代码示例

    //01 字面量方式创建对象obj
    var obj = {name:"wendingding",age:18};

    //02 使用Object.create方法来创建新对象
    var o = Object.create(obj);
    //o是一个空对象,o.__proto__指向obj对象
    console.log(o);
    //wendingding 访问原型对象obj上面的name属性
    console.log(o.name);

    //03 测试传入null的情况
    var o1 = Object.create(null);
    //打印结果为空对象,No properties 该对象身上没有任何成员
    console.log(o1);

    //04 测试传入Object.prototype的情况
    var o2 = Object.create(Object.prototype);
    //o2 是空对象,等价于{}
    console.log(o2);

1.3 javaScript中对象的操作

我们知道对象可以简单理解为键值对的集合,通过前面的阅读我们已经了解到如何创建对象,接下来我们接着探讨对象内部键值对的相关操作。

对象属性和方法的访问方式:点语法或者是[]语法。
对象属性和方法的操作方式:对象的操作方式和数据的操作方式保持一致,可以简单总结为增删改查和遍历操作。

代码示例

        //00 提供obj对象
    //通过字面量方式创建obj对象,该对象现在拥有name属性和showName方法
    //因使用字面量方式创建,所有obj的原型对象(__proto__)指向object.prototype
    var obj = {
        name:"wendingding",
        showName:function () {
            console.log(this.name);
        }
    };

    //01 添加属性或方法
    //a 使用点语法来为obj对象添加age属性和showAge方法
    obj.age = 18;
    obj.showAge = function (){
        console.log(this.age);
    };

    //b 使用中括号语法来为obj对象添加age属性和showAge方法
    obj["class-name"] = 41;
    obj["showClassName"] = function () {
        console.log(this["class-name"]);
    };

    //02 修改属性或方法
    //如果对象的属性已经存在,那么设置该属性的时候表示修改
    obj.age = 20;
    obj.showAge = function (){
        console.log("年龄" + this.age);
    };

    //03 查询属性或者调用方法
    console.log(obj.name);      //wendingding
    console.log(obj["age"]);    //20
    obj.showName();             //wendingding
    obj["showName"]();          //注意,不推荐使用这种方法

    //04 删除对象中的属性或方法
    //语法形式:delete 对象.属性 | delete 对象[属性]
    delete obj.name;
    delete obj["showName"];
    console.log(obj);

    //05 对象的遍历
    for (key in obj)
    {
         console.log(key, obj["key"]);
    }

delete关键字说明

01 具体使用:
        (1) 可以用来删除对象中指定的属性
        (2) 用来删除没有使用var关键字声明的变量  delete 变量名|window.变量
02 使用注意点
        (1) 关键字在使用的时候有返回值,true|false 删除成功返回true
        (2) 删除对象中不存在的属性,返回true
        (3) 使用var声明的变量不能被直接删除
        (4) 不能删除使用var声明的全局变量但是可以删除直接添加在window上面的属性
        (5) 如果删除数组中的元素(数组也是对象)则数组中对应的元素内容被替换为undefined,索引保留。

对象属性说明

❐ 对象的属性名可以是任意字符串,包括空字符。
❐ 对象的属性名如果是合法的JavaScript标识符,则不必强制要求使用双引号括住属性名。
❐ 属性值可以是任何值(包括undefined)。
❐ 如果对象的属性名并非合法标识符,则建议使用[]语法来访问对象。
❐ 标识符规范:字母开头,后面跟1个或多个下划线、数字或字母。


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

推荐阅读更多精彩内容

  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,089评论 0 6
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,092评论 0 21
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,510评论 0 5
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,199评论 0 4
  • 说到写自己的事心里还是蛮心酸的!在我的脑海里总是会到许多不开心的事,控制不了自己的情绪就会越想越糟,唉……真的是不...
    顺鑫梦阅读 682评论 0 0