资讯专栏INFORMATION COLUMN

JS对象---奥义:真の由浅入深

qianfeng / 3335人阅读

摘要:容易理解创建一个构造函数并使用该函数和操作符初始化对象。被继承的对象被称作原型,并且继承的属性可能通过构造函数的对象找到。

This is my first blood!

第一次在segmentfault上写(chao)文章。

内容提要:认(wu)真(liao)的整理一下javascript对象的知识,人家还是菜鸟,必须要搞懂啊。

PS:
1.真的菜,所以看到文章的同学,推荐采用随缘阅读法,请自行忽略里面充斥大量的,哦不,巨量的错误、bug。
2.如果您愿意指出我的错误,那最好不过了,寡人谢谢!(参见文章中的‘求大腿’的字样)
3.不过,如果你指望以此契机,期待一场与程序媛之间的轰轰烈烈的深刻的交互,那您还是绕道而行吧。哥真的是汉子,不是童瑶。
4.说是笔记,大部分的代码都是copy的,不爽的同学,直接看参考资料吧。

一 参考资料

1.MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects
2.文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object

二 全都是对象

在 JavaScript 中,几乎所有的东西都是对象。所有的原生类型除了 null 与 undefined 之外都被当作对象。它们可以被赋予属性(某些类型的被赋予的属性不能被持久化),并且它们都有对象的全部特征。

三 创建对象

两种创建方式:

1.对象初始化器(Object Initializer)创建对象。(容易理解)
2.创建一个构造函数并使用该函数和 new 操作符初始化对象。(容易装逼)

容易理解的创建方式

模版:

    var obj = { property_1:   value_1,   // property_# may be an identifier...
                2:            value_2,   // or a number...
                // ...,
                "property n": value_n }; // or a string

实例:

var lolhero = new Object();
lolhero.basicSkill = "Q、W、E";
lolhero.bigSkill = "R only";
lolhero.commotSkill = "D&F";

//两种访问方式
console.log(lolhero["basicSkill"]);//采用类似关联数组的方式访问
console.log(lolhero.basicSkill);//直接访问
容易装逼的创建方式

使用构造函数,需要两步!!!

通过创建一个构造函数来定义对象的类型。首字母大写是非常普遍而且很恰当的惯用法。

通过 new 创建对象实例。

写的太好直接copy过来了

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

var Car = new Car("Eagle", "Talon TSi", 1993);
var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);

一个对象的属性值可以是另一个对象。例如,假设你按如下方式定义了 person 对象:

function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}

然后按如下方式创建了两个 person 实例:

    var rand = new Person("Rand McKinnon", 33, "M");
    var ken = new Person("Ken Jones", 39, "M");

那么,你可以重写 car 的定义以包含一个拥有它的 owner 属性,如:

    function Car(make, model, year, owner) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.owner = owner;
    }

你可以按如下方式创建新对象:

    var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
    var car2 = new Car("Nissan", "300ZX", 1992, ken);

注意在创建新对象时,上面的语句将 rand 和 ken 作为 owner 的参数值,而不是传入字符串字面量或整数值。接下来你如果想找出 car2 的拥有者的姓名,你可以访问如下属性:

car2.owner.name

注意你总是可以为之前定义的对象增加新的属性。例如,语句

car1.color = "black";

为 car1 增加了 color 属性,并将其值设为 "black." 然而,这并不影响其他的对象。想要为某个类型的所有对象增加新属性,你必须将属性加入到 car 对象类型的定义中。

PS:发现没,虽然第二种创建对象的方式看起来不那么自然.
但是却好用,容易移植,容易重新定义,容易复用。所以,还是装逼好啊!

Object.create 创建对象

感觉挺麻烦的,反正已经有了其他创建方式,暂且不管他了。

(这玩意儿一般用的多吗?多用来处理什么功能?求大腿

四 属性 如果对象的属性名千奇百怪怎么办?

这样也是允许的(太难为js了吧),有谁这么{{BANNED}}的用各种类型的属性名,算了,{{BANNED}}总是有的。

    var myObj = new Object(),
    str = "myString",
    rand = Math.random(),
    obj = new Object();

    myObj.type              = "Dot syntax";
    myObj["date created"]   = "String with space";
    myObj[str]              = "String value";
    myObj[rand]             = "Random Number";
    myObj[obj]              = "Object";
    myObj[""]               = "Even an empty string";

    console.log(myObj);
当然了,属性值,也可以是个变量
    var propertyName = "make";
    myCar[propertyName] = "Ford";

    propertyName = "model";
    myCar[propertyName] = "Mustang";
对象的属性太多,用for(var i in obj){}来遍历它

hasOwnProperty: 如果 object 具有指定名称的属性,那么JavaScript中hasOwnProperty函数方法返回 true;反之则返回 false。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。

    function showProps(obj,objName) {
        var result = "";
        for(var i in obj){
            if( obj.hasOwnProperty(i) ) {
                result += objName+"."+i+" = "+obj[i]+"
";
            }
        }
        return result;
    }

    console.log(showProps(myObj,"myobj"));

从 ECMAScript 5 开始,有三种原生的方法用于列出或枚举对象的属性:

for...in 循环
该方法依次访问一个对象及其原型链中所有可枚举的属性。

Object.keys(o)
该方法返回一个对象 o 自身包含(不包括原型中)的所有属性的名称的数组。

Object.getOwnPropertyNames(o)
该方法返回一个数组,它包含了对象 o 所有拥有的属性(无论是否可枚举)的名称。

在 ECMAScript 5 中,没有原生的方法枚举一个对象的所有属性。然而,可以通过以下函数完成:

    function listAllProperties(o){
        var objectToInspect;
        var result = [];

        for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
            result = result.concat(Object.getOwnPropertyNames(objectToInspect));
        }

        return result;
    }

上面的这个方法,可以访问所有的可枚举和不可枚举的属性。

PS:对象里面的属性有可枚举和不可枚举两种。(不甚理解什么是不可枚举,求大腿!)

五 继承

所有的 JavaScript 对象继承于至少一个对象。被继承的对象被称作原型,并且继承的属性可能通过构造函数的 prototype 对象找到。

六 为对象类型定义属性

你可以通过 prototype 属性为之前定义的对象类型增加属性。这为该类型的所有对象,而不是仅仅一个对象增加了一个属性。下面的代码为所有类型为 car 的对象增加了 color 属性,然后为对象 car1 的 color 属性赋值:

Car.prototype.color = null;
car1.color = "black";
七 如果我想给对象添加方法怎么办?

两种方式:

objectName.methodname = function_name;
var myObj = {
    myMethod: function(params) {
        // ...do something
    }
};

前面创建对象的完整写法:

    function Car(make, model, year, owner) {

        //注意displayCar函数里面this和外面的this指向的是同一个car对象!
        function displayCar() {
            console.log("this2",this);
            var result = "A Beautiful " + this.year + " "
            + this.make + " " + this.model;
            return result;
        }

        this.make = make;
        this.model = model;
        this.year = year;
        this.owner = owner;
        console.log("this1",this);
        this.displayCar = displayCar;
    }

    var car = new Car("福特汽车","奔驰",1234,"maomaoliang");
    console.log(car.displayCar());

或者

function Car(make, model, year, owner) {
    this.make = make;
    this.model = model;
    this.year = year;
    this.owner = owner;
    this.displayCar = function(){
        //...
    };
}
八 删除属性

用 delete 操作符删除一个不是继承而来的属性。下面的例子说明如何删除一个属性:

//Creates a new object, myobj, with two properties, a and b.
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;

//Removes the a property, leaving myobj with only the b property.
delete myobj.a;
九 比较对象

在 JavaScript 中 objects 是一个引用类型。将两个引用相同的对象想比较会返回 true; 将两个方法和属性相同的对象相比较,会返回 false;

// fruit object reference variable
var fruit = {name: "apple"};

// fruitbear object reference variable
var fruitbear = {name: "apple"};

fruit == fruitbear // return false

fruit === fruitbear // return false
// fruit object reference variable
var fruit = {name: "apple"};

// fruitbear object reference variable
var fruitbear = fruit;  // assign fruit object reference to fruitbear object reference variable

// here fruit and fruitbear pointing to same object called fruit
fruit == fruitbear // return true

// here fruit and fruitbear pointing to same object called fruit
fruit === fruitbear // return true

意思就是,用的时候要比较引用,而不是比较全部咯?求大腿

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78594.html

相关文章

  • 新技能GET!在前端表格中花式使用异步函数的奥义

    摘要:实践专家用户的花式使用实践专家用户的花式使用实例演示实例演示我们用一个简单的例子,看看在前端电子表格单元格计算中,如何使用异步函数。这一次用户使用异步函数从服务器获取当前服务名,并在显示出来。背景60年代时,操作系统中独立运行的单元通常是进程。但随着计算机技术的发展,人们发现在进程运行过程中,创建、撤销与切换都要花费较大的时空开销。到了80年代为了解决这一问题,出现了更小的独立运行基本单位—...

    番茄西红柿 评论0 收藏2637
  • 好棒的前端文章 - 收藏集 - 掘金

    摘要:你应该知道的种设计模式前端掘金每位开发者都努力写出可维护的易读的可复用的代码。继承关系本前端书籍整理,高清前端掘金发现了一个下载前端书籍的地方,分享给大家。 你应该知道的 4 种 JavaScript 设计模式 - 前端 - 掘金每位开发者都努力写出可维护的、易读的、可复用的代码。随着应用变得越来越大,代码的结构也越来越重要。设计模式验证了解决这个挑战的重点——在特定环境中,对同类事物...

    Maxiye 评论0 收藏0
  • js基础常用知识点由浅入深整理篇

    摘要:因为同一时间,只能处理一个异步,这又牵扯到单线程问题了。然后控制台默默打印了个目前前端,异步主要为前后端交互以及定时器,仅仅说前端,如果说的话,还有文件读取等其他的方面会异步。 此篇文章完全按照我个人理解去写。 1.何为JS 先说说js干啥的。不负责点说,js就是操作浏览器的。 有人可能说nodeJS,nodeJS严格意义上只能说是用的ES,因为他没有dom ,也没有bom。 简单点说...

    Zack 评论0 收藏0
  • 从项目中由浅入深的学习typescript (3)

    摘要:序列文章从项目中由浅入深的学习微信小程序和快应用从项目中由浅入深的学习前言为什么会有大家有没想过这个问题原因是是弱类型编程语言也就是申明变量类型可以任意变换。是的超集,也相当于预处理器本文通过一个项目来让你快速上手。 showImg(https://segmentfault.com/img/bVbruJw?w=1024&h=768); 序列文章 从项目中由浅入深的学习vue,微信小程序...

    ninefive 评论0 收藏0
  • 从项目中由浅入深的学习koa 、mongodb(4)

    摘要:序列文章从项目中由浅入深的学习微信小程序和快应用从项目中由浅入深的学习从项目中由浅入深的学习前言的出现前端已经可以用一把梭从前端写到后台。 showImg(https://segmentfault.com/img/bVbrRI5?w=1920&h=1080); 序列文章 从项目中由浅入深的学习vue,微信小程序和快应用 (1)从项目中由浅入深的学习react (2)从项目中由浅入深的学...

    null1145 评论0 收藏0

发表评论

0条评论

qianfeng

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<