资讯专栏INFORMATION COLUMN

全面学习javascript中的对象

leo108 / 3062人阅读

摘要:表示对象的父对象,直接继承的对象。的目的是让函数隐式的使用对象。内置的构造函数在中,有几个内置的构造函数,可以直接拿来使用。如果返回的是一个对象,那么返回值为这个对象。

对象的基础 对象的定义

对象是一组由若干个无序的键值对(key/value)组成的数据集合 ,在 javascript 中所有的数据都可以被视作对象。每一个键值对又可以叫做“成员(members)”。

对象(object)的创建(3种方式)

对象字面量(对象初始化器)

构造函数

Object.create() es5的创建对象的方式,可以指定原型对象

//方式1
var me = {
    name: "qingzhui",
    age: 25
};

//方式2
var me = new Object();
me.name = "qingzhui";
me.age = 25;

//方式3
var me = Object.create(Object.prototype, {
    name: {
        value: "qingzhui",
        enumerable: true,
        wriable: true,
        configurable: true
    },
    age: {
        value: 25,
        enumerable: true,
        wriable: true,
        configurable: true
    }
});
键名(key),成员的名称

键名,键值对中的 key,我们可以将之称为成员的名称。对象中所有的键名都是字符串,所有加不加引号都可以。必须要加引号的情况:如果_键名不是数字,又不符合标识符的条件_,就必须加上引号。

var obj = {
    1: "name", // 数字可以不加引号
    "2name": "name2" // 不符合条件的,必须加引号
};
键名(key),属性

键名,又可以称作属性(property)。它的键值_可以是任何数据类型,_如果它的值是一个函数的话,我们可以把这个属性叫做方法(method)

属性的分类

属性有两种类型:数据属性(data property)、访问属性(accessor property)。

数据属性(data property)

除开访问属性(get/set)之外,都是数据属性。

访问属性(accessor property)

访问属性又叫 geter/seter 属性。它只有2种 getter property / setter property。

getter property 当访问一个对象属性时,会隐式的调用一个函数,返回一个生成值。

setter property 当赋值一个对象属性时,会隐式的调用一个函数,返回一个生成值。

var me = {
    name: "qingzhui",
    _age: 26,
    get age(){
        return "您真的年龄是:" + _age;
    }, // 语法 get property_name(){ statement }
    set age(num){
        return _age = num + 2;
    } // 语法 property_name(parameter_name) { statement }
};

me.age = 28;

console.log(me.age); // "您真的年龄是:30"

根据属性的所属,可以把属性分为两种自身属性(own property)、继承属性(inherited property)。

自身属性(own property)

就是在对象自身定义的属性,我们称之为自身属性。

继承属性(inherited property)

通过原型链(prototype chain),继承自父对象、或是祖先对象的属性,我们称之为继承属性。

属性的特性(property attribute)

属性的特性,用来描述属性的相关信息。在数据属性中,属性拥有4(_writable、enumerable、configurable、value_)种特性,用来表示这个属性的相关信息。在访问属性中,get 属性拥有3(_get、enumerable、configurable_)种特性,set属性拥有3(_set、enumerable、configurable_)种特性。

value

属性的属性值。

wriable

true 或者 false,表示这个属性_是否可以设置_。

enumerable

true 或者 false, 表示这个属性_是否可以在循环属性中被枚举_。

var me = {
    name: "qingzhui",
};

console.log(me.propertyIsEnumerable("name")); // true
configurable

true 或者 false,表示这个属性是否_可以被删除或者属性值是否可以改变_。

Object.getOwnPropertyDescriptor(obj, "prop")
var o1 = Object.create(Object.prototype, {
    "name": {
        value: "qingzhui"
    }
});

var o2 = {
    name: "qingzhui"
};

console.log(Object.getOwnPropertyDescriptor(o1, "name"));
//{configurable: false,enumerable: false,value: "qingzhui",writable: false}

console.log(Object.getOwnPropertyDescriptor(o2, "name"));
//{configurable: true, enumerable: true, value: "qingzhui", writable: true}
与属性特性相关的方法

Object.defineProperty(obj, "prop", descriptor) 定义或修改一个属性

Object.defineProperties(obj, props) 定义或修改多个属性

Object.create(proto, properiesObject ) 创建一个新的对象

对象的内部属性(internal slots)

对象的内部属性只是用来描述对象的相关信息、不属于对象的真正的属性,不可以访问。你可以把它当做特殊的隐藏属性。

[[]prototype]] obejct 表示对象的父对象,直接继承的对象。

[[extensible]] boolean 表示是否可以添加属性

[[class]] string 表示对象的分类

属性的操作 读取属性(read property)

读取属性有两种方法,一种是点运算符,一种是方括号运算符

var me = {
    name: "qingzhui";
};

//方式1
console.log(me.name); // "qingzhui"

//方式2
console.log(me["name"]); // "qingzhui"

console.log(me.age); // 读取一个不存在的属性返回 "undefined"

console.log(me.toSting) // 读取自身没有的属性,会在原型链上找到最近的返回

需要注意的是,_点运算符与方括号的不同点_:

方括号运算符可以使用表达式。

方括号可以读取键名为数字、不符合标识符条件的、关键字和保留字的属性。

读取一个不存在的属性,返回的是 undefined 。可以利用这一点用来判断变量是否声明。

if(a in window){
    // a 声明过
}else{
    // a 未声明
}
添加属性(add property)

点运算符和方括号运算符不仅可以读取属性,还可以对属性进行赋值。

var me = {
    name: "qingzhui"
};

me.age = 26; // 使用点运算符添加 age 属性

me["like"] = "music"; // 使用方括号运算符添加 like 属性

Object.defineProperty() ES5 的方法,用来新增或者修改一个已经存在的属性。

var me = {
    name: "qingzhui"
};

Object.defineProperty(me, "age", {
    value: 26,
    writable: true, // 不定义,默认 false
    enumerable: true, // 不定义,默认 false
    configurable: true // 不定义,默认 false
});

Object.defineProperties() ES5的方法,用来新增或者修改多个自有属性,并返回该对象。

var me = {
    name: "qingzhui"
};

Object.defineProperties(me, {
    "age": {
        value: 26
    },
    "sex": {
        value: "boy",
        wriable: false,
        enumerable: true,
        configurable: false
    }
});
修改属性(modify property)
var me = {
    name: "qingzhui"
};

me.name = "scl"; // 可以使用点运算符 对 name 属性重新赋值,达到修改的目的
删除属性(delete property)

使用 [delete](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/delete) 运算符,可以删除对象的属性,在严格模式下,删除一个不可配置的属性(non-configurable),会抛出异常,在非严格模式下,返回 false,其它情况都返回 true

var me = {
    name: "qingzhui"
};

delete me.name; // true
遍历对象的属性 for-in

可以使用 in 运算符,来判断某个属性是否在指定的对象中。用[for-in](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in),任意序迭代一个对象的可枚举属性。每个不同的属性,语句都会被执行一次。

//创建 person 对象
var person = {
    species: "动物",
    sex: "男"
};

//创建 me 对象,让其 继承 person
var me = Object.create(person, {
    name: {
        value: "qingzhui",
        wriable: true,
        enumerable: true, // 设置可枚举
        configurable: true
    },
    age: {
        value: 26,
        wriable: true,
        enumerable: false, // 设置不可枚举
        configurable: true
    }
});

var arr = [];

for(var a in me){
    arr.push(a);
}

console.log(arr); // ["name", "species", "sex"]

遍历的是对象所有_可遍历(enumberable)的属性_,会跳过不可遍历的属性

它不仅遍历对象自身的属性,_还遍历继承的属性_

Object.keys() es5方法

使用 Object.keys(obj) 可以遍历_自身所有可以枚举的属性_,返回所有可枚举自身属性的属性名组成的数组。

console.log(Object.keys(me)); // ["name"]
Object.getOwnPropertyNames(obj) ES5方法

使用 Object.getOwnPropertyNames(obj) 可以遍历_自身所有的属性_,返回所有自身属性的属性名组成的数组。

console.log(Object.getOwnPropertyNames(me)); // ["name", "age"]
检查属性是否存在

hasOwnProperty() 如果自身含有这个属性,返回 true,否则 false。

var me = {
    name: "qingzhui"
};

console.log(me.hasOwnProperty("name")); // true

console.log(me.hasOwnProperty("age")); // fasle

in 运算符,用来判断自身或者继承来的属性是否在这个对象中。

var person = {
    species: "动物",
    sex: "男"
}

var me = Object.create(person);

me.name = "qingzhui";

console.log("name" in me); // 检查自身的属性 true

console.log("sex" in me); // 检查继承的属性 true

console.log("job" in me); // 检查没有的属性 fasle
对象的引用

对象的引用是按址引用的,如果不同的变量引用同一个对象,它们会指向_同一个内存地址_,修改 其中一个变量,会影响到其它的变量。

var me = {
    name: "qingzhui"
};

var qingzhui = me; // 让 qingzhui 引用 me 对象

qingzhui.name = "scl"; // 修改 qingzhui 的 name 属性

console.log(me.name); // "scl" 改变了 me 的 name 属性  
对象的分类

标准对象(standard object)

如 Object、Aaary等

宿主对象(hosted object)

如DOM中的 document,BOM中的 window ,nodejs中的 http

自定义对象(user-define object)

var o = {};

对象深入 原型和继承 原型(prototype)

在 javascript 中,每一个对象都有一个内部的相关信息叫 prototype ,可以用 [[prototype]]表示。

[[prototype]]的值是一个对象或者是 null ,我们把这个对象称之为原型对象,或者说是父对象。

继承(inheritance)

在 javascript 中,查找属性的时候,先从自身查找,如果找不到,就在其父对象,一直往上找,直到 null,这种机制就叫做继承

原型链(prototype chain)

一个对象的父对象,父对象的父对象,形成一个链,称之为原型链(prototype chain)

不是所有的对象都有父对象,Object.prototype 是所有对象的根,它的原型对象(父对象)是 null。

查找对象的原型对象(父对象) __proto__

返回对象的原型对象(父对象),在 ES6 之前,只有部分浏览器支持,在ES6 被正式纳入标准。
_proto 和 [[prototype]] 指向同一个对象,即它的原型对象(父对象)。

funtion Person(){
    //
}

var me = new Person();

console.log(me.__proto__ === Person.prototype); // true
getPrototypeOf()

返回指定对象的原型对象。

Object.getPrototypeOf(object)
isPrototypeOf()

测试一个对象是否存在于另一个对象的原型链上。

obj.prototype.isPrototypeOf(object)
资源

从本质认识JavaScript的原型继承和类继承

Javascript面向对象编程(三):非构造函数的继承

定义对象的父对象

使用 Object.create(myparent, )

定义一个没有 return 的构造函数 F,然后 F.prototype = myparent,使用 new F()

限制对象的一些方法
Object.isExtensible()  // 判断是否可扩展

Object.preventExtensions()

Object.isSeal() // 判断是否密封

Object.seal()

Object.isFrozen() // 判断是否冻结

Object.freeze()
确定对象的子类型
Object.prototype.toString.call(myObj);

console.log(Object.prototype.toString.call({})) // "[object Object]"

复制对象

方法一(深拷贝)

Json.parse(Json.stringify(obj));

方法二 (es6)

Object.assign(target, ...sources)

javascript中的深拷贝和浅拷贝?

深入剖析 JavaScript 的深复制

判断对象是否相等
function is_obj_equal(obj1, obj2){
    var keys1 = Object.keys(obj1).sort();
    var keys2 = Object.keys(obj2).sort();

    if(keys1.length !== keys2.length){
        return false;
    }

    if (!keys1.every(function(k, i){ return (k === keys2[i]); })){
        return false;
    }

    return keys1.every(function(kk) {
        var v1 = obj1[kk];
        var v2 = obj2[kk];
        if ( Array.isArray(v1) )  {
            return is_array_equal(v1,v2);
        } else if ( typeof v1 === "object" && v1 !== null) {
            return is_obj_equal(v1,v2);
        } else {
            return  v1 === v2;
        }
    });
}
面向对象编程 this

在 javascript 中,当一个函数被调用时,它有一个相关值被称之为 ‘ ThisBinding ’

在函数定义时,‘ ThisBinding ’ 是用 this 表示。

‘ ThisBinding’ 的目的是让函数隐式的使用对象。

this 的值是什么?

当一个函数被当做一个对象的方法调用时,this 的值是指调用这个函数的对象。

var f = function(){
    return this;
};

var o = { f1: f}; // this 是 o

console.log(o == o.f1()); // true

当一个函数,使用 new 调用, this 的值是这个新创建的对象。

var F = function(){
    this.name = "qingzhui";
};

var me = new F(); // this 是 me

console.log(me); // { name: "qingzhui"}

当一个函数,是在全局上下文直接调用,如果是严格模式,this 的值是 undefined 。非严格模式下是全局对象(如 window)。

"use strict"

var f = function(){
    return this;
};

console.log(f()); // this 是 undefined

当一个函数是在一个函数里面,函数被调用时,如果是严格模式,this 的值是 undefined ,否则是全局对象

"use stric"

var f = function(){
    var h = function(){
        return this; // this 是 undefined
    };

    return h();
};

console.log(f() === undefined); // true

var o = {
    p = function(){
        var f = function(){
            return this; // this 是 undefined
        };

        return f();
    }
};

console.log(o.p() === undefined); // true
资源

js 中 this 关键字详解

详解this

构造函数(constructor)

当一个函数被设计使用 new 调用的时候,我们叫这个函数为构造函数。构造函数是用来创建函数的一种方式。

内置的构造函数

在 JavaScript 中,有几个内置的构造函数,可以直接拿来使用。

var o = new Object();

var arr = new Array();

var fun = new Function();

var date = new Date();

var reg = new Regex();
原始类型值的包装器
var str = new String("a");

var num = new Number(1);

var boolean = new Boolean(true);

构造函数应该已大写字母开始。

原型属性(prototype)

在 JavaScript 中,每一个函数有一个特殊的属性 prototype

var f = function(){

};

console.log(f.hasOwnProperty("prototype")); // true

console.log(Object.hasOwnProperty("prototype")); // true

console.log(Array.hasOwnProperty("prototype")); // true

用户自定义的函数,它的原型属性的值默认值:{ constructor: f}

var f = function(){

};

console.log(f.hasOwnProperty("prototype")); // true

console.log(Object.getOwnpropertyNames(f.prototype).lenght === 1); // true

console.log(Object.getOwnpropertyNames(f.prototype)[0] === constructor); // true

console.log(Object.getOwnPropertyDescriptor(f.protptype, "constructor")); // { value: f, writable: true, enumerable: false, configurable: true}

内置的函数,它的原型属性的默认值是

Object.prototype 就是 Object.prototype, Object.prototype 被设计为 new Object()新对象的父对象

在严格模式下,内置的构造函数的原型属性不能被改变,否则会报错。

操作符 new

操作符 new 是用来和函数一起,创建一个对象。

// 语法
new function_name(args);
new 是如何工作的?

每一个函数都有一个属性叫做原型属性(prototype

它的值默认是{ constructor: F}

创建一个新的空对象,将它的父对象设置为 F.prototype

执行构造函数,把 this 指向这个新对象

如果构造函数没有返回值,或者返回的不是一个对象,那么 新对象 将作为返回值。如果返回的是一个对象,那么返回值为这个对象。

var F1 = function(){
    this.name = 1;
};

var F2 = function(){
    this.name = 2;
    return 3;
};

var F3 = function(){
    this.name = 3;
    return {
        name: "qingzhui"
    };
};

var f1 = new F1(); // { name: 1}
var f2 = new F2(); // { name: 2}
var f3 = new F3(); // { name: "qingzhui"}
使用 new 创建的对象的父对象是什么?

如果构造函数F返回的不是一个对象,或者没有返回值,那么它的父对象只指 F.prototype

如果构造函数F有返回语句,返回一个对象,要看返回的对象是怎么创建的。来判断它的父对象。

继承

全面理解面向对象的 JavaScript

文章同时发表在:
http://blog.qingzhui.net/post...

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

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

相关文章

  • H5学习

    摘要:为此决定自研一个富文本编辑器。本文,主要介绍如何实现富文本编辑器,和解决一些不同浏览器和设备之间的。 对ES6Generator函数的理解 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。 JavaScript 设计模式 ② 巧用工厂模式和创建者模式 我为什么把他们两个放在一起讲?我觉得这两个设计模式有相似之处,有时候会一个设计模式不能满...

    aristark 评论0 收藏0
  • 前端开发周报: CSS 布局方式与JavaScript数据结构和算法

    摘要:如果没有学习过计算机科学的程序员,当我们在处理一些问题时,比较熟悉的数据结构就是数组,数组无疑是一个很好的选择。 showImg(https://segmentfault.com/img/bVTSjt?w=400&h=300); 1、常见 CSS 布局方式详见: 一些常见的 CSS 布局方式梳理,涉及 Flex 布局、Grid 布局、圣杯布局、双飞翼布局等。http://cherryb...

    huhud 评论0 收藏0
  • 前端开发周报: CSS 布局方式与JavaScript数据结构和算法

    摘要:如果没有学习过计算机科学的程序员,当我们在处理一些问题时,比较熟悉的数据结构就是数组,数组无疑是一个很好的选择。 showImg(https://segmentfault.com/img/bVTSjt?w=400&h=300); 1、常见 CSS 布局方式详见: 一些常见的 CSS 布局方式梳理,涉及 Flex 布局、Grid 布局、圣杯布局、双飞翼布局等。http://cherryb...

    ?xiaoxiao, 评论0 收藏0

发表评论

0条评论

leo108

|高级讲师

TA的文章

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