JS语言核心——“对象”

  • 属性特性(property attribute):每个属性与之相关的值:

    • 可写(writable attribute);

    • 可枚举(enumerable attribute);

    • 可配置(configurable attribute);

  • 对象特性(object attribute):

    • 原型(prototype);

    • 类(class);

    • 扩展标记(extensible flag);

  • 三类js对象:

    • 内置对象(native object):由ECMAScript规范定义的对象或类;

    • 宿主对象(host object):由js解释器所嵌入的宿主环境定义的;

    • 自定义对象(user-defined object):由运行中的js代码创建的对象

  • 两类属性:

    • 自有属性(own property):直接在对象中定义的属性;

    • 继承属性(inherited property):在对象的原型对象中定义的属性;

1 创建对象

三种方法:直接量;newObject.create()函数;

1.1 对象直接量

语法:

var o = {};

1.2 通过new创建对象

语法:

var o = new Object();

1.3 原型

通过Object.prototype获得对原型对象的引用

1.4 Object.create()

第一个参数是这个对象的原型;第二个可选参数是对对象的属性进行进一步描述



//创建一个普通的空对象
var o = Object.create(Object.prototype);

2 属性的查询和设置

[].

2.1 作为关联数组的对象

JavaScript对象都是关联数组(字典、映射、散列等)

2.2 继承

[暂跳]

2.3 属性访问错误

当访问不存在的对象的属性就会报错,可以通过下面方法避免出错:


var book = {};
var len;
if (book.subtitle) {
    len = book.subtitle.length;
}
console.log(len); //undefined

//或者
var book = {subtitle:"toJSON"};
var len;
len = book && book.subtitle && book.subtitle.length; //&&运算符的短路行为
console.log(len); //6
//当左操作数是真值时,“&&”运算符将计算右操作数的值并将其返回作为整个表达式的计算结果

2.4 删除属性

delete运算符不能删除继承属性

3 检测属性

5种方法:

in运算符,检测自有属性和继承属性

var o = {name:"Oliver",age:18,nothing:undefined};
console.log("name" in o); //True
console.log("toString" in o); //True
console.log("nothing" in o); //True

hasOwnProperty方法,检测自有属性

var o = {name:"Oliver",age:18,nothing:undefined};
console.log(o.hasOwnProperty("toString")); //False
console.log(o.hasOwnProperty("name")); //True

propertyIsEnumerable方法,检测自有可枚举的属性

var o = {name:"Oliver",age:18,nothing:undefined};
console.log(o.propertyIsEnumerable("toString")); //False
console.log(o.propertyIsEnumerable("name")); //True

"!=="方法,检测属性是否为undefined

var o = {name:"Oliver",age:18,nothing:undefined};
console.log(o.name !== undefined); //True
console.log(o.nothing !== undefined); //False

有一种场景只能使用in运算符。in可以区分不存在的属性和存在但是值为undefined的属性:

var o = {name:"Oliver",age:18,nothing:undefined};
console.log("nothing" in o); //True
console.log(o.nothing !== undefined); //False
delete o.nothing;
console.log("nothing" in o); //False
console.log(o.nothing !== undefined); //False

需要注意的是,"!=="可以区分undefined和null

4 枚举属性

把p中的可枚举属性赋值到o中,并返回o,如果有同名属性则覆盖o中的属性

function extend (o, p) {
    for (var prop in p) {
        o[prop] = p[prop];
    }
    return o;
}

如:

var p = {name:"Oliver",age:18,nothing:undefined};
var o = {};

function extend (o, p) {
    for (var prop in p) {
        o[prop] = p[prop];
    }
    return o;
}

console.log(extend(o,p));

将p中的可枚举属性复制到o中,并返回o,如果有同名属性则不覆盖o中的属性

function merge (o, p) {
    for (var prop in p) {
        if (o.hasOwnProperty(prop)) {
            continue;
            o[prop] = p[prop];
        }
    }
    return o;
}

如:

var p = {name:"Oliver",age:18,nothing:undefined};
var o = {name:"Oli"};

function merge (o, p) {
    for (var prop in p) {
        if (o.hasOwnProperty(prop)) {
            continue;
            o[prop] = p[prop];
        }
    }
    return o;
}

console.log(merge(o,p).name); //Oli

如果o中的属性在p中没有同名属性,则从o中删除这个属性

function restrict (o, p) {
    for (var prop in o) {
        if (!(prop in p)) {
            delete o[prop];
        }
    }
    return o;
}

如:

var p = {age:18,nothing:undefined};
var o = {name:"Oli"};

function restrict (o, p) {
    for (var prop in o) {
        if (!(prop in p)) {
            delete o[prop];
        }
    }
    return o;
}

console.log(merge(o, p).name); //undefined

如果o中的属性在p中存在同名属性,则从o中删除这个属性

function subtract (o, p) {
    for (var prop in o) {
        if (prop in p) {
            delete o[prop];
        }
    }
    return o;
}

如:

var p = {name:"Oliver",age:18,nothing:undefined};
var o = {name:"Oli"};

function subtract (o, p) {
    for (var prop in o) {
        if (prop in p) {
            delete o[prop];
        }
    }
    return o;
}

console.log(subtract(o, p).name); //undefined

返回一个新对象,这个对象同时拥有o的属性和p的属性,如果有重名属性,使用p中的属性值

function union (o, p) {
    for (var prop in o) {
        if (prop in p) {
            o[prop] = p[prop]
        }
    }
    return o;
}

如:

var p = {name:"Oliver",age:18,nothing:undefined};
var o = {name:"Oli"};

function union (o, p) {
    for (var prop in o) {
        if (prop in p) {
            o[prop] = p[prop]
        }
    }
    return o;
}

console.log(union(o, p).name); //Oliver

返回一个新对象,这个对象同时拥有o的属性和p的属性,如果重名,使用o的值

function intersection (o, p) {
    for (var prop in o) {
        if (prop in p) {
            delete p[prop];
        }
    }
    return o;
}

如:

var p = {name:"Oliver",age:18,nothing:undefined};
var o = {name:"Oli"};

function intersection (o, p) {
    for (var prop in o) {
        if (prop in p) {
            delete p[prop];
        }
    }
    return o;
}

console.log(intersection(o, p).name); //Oliver

返回一个数组,这个数组包含的是o中可枚举的自有属性的名字

5 属性getter和setter

  • 存取器属性(accessor property):由getter和setter定义的属性;它不同于数据属性(data property),数据属性只有一个简单的值;

语法:

var o = {
    data_prop: value,/*这是普通数据属性*/
get accessor_prop(){/*这里是函数体*/},
set accessor_prop(value){/*这里是函数体*/}
};

这个定义没有使用function关键字,而是使用get和(或)set

存取器属性是可以继承的


var o = {
    n: 0,/*这是普通数据属性*/
get next(){return this.n++},
set next(n){this.n = n}
};
o.next = 10; //setter
console.log(o.next) //getter

6 属性的特性

  • 存取器属性的四个特性:读取(get)、写入(set)、可枚举性(enumerable)和可配置性(configurable)

  • 数据属性的四个特性:值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)

获得某个对象特定属性的属性描述符

Object.getOwnPropertyDescriptor()方法:


//name数据属性
let o = {
    name: "Oliver",
    get transferName(){return this.name},
    set transferName(value){this.name = name}
};
let result = Object.getOwnPropertyDescriptor(o, "name");
console.log(result); //Object
for (let name in result) {
    console.log(name, result[name]);
}
//value Oliver
//writable True
//enumerable True
//configurable True

//transferName存取器属性
let o = {
    name: "Oliver",
    get transferName(){return this.name},
    set transferName(value){this.name = name}
};
let result = Object.getOwnPropertyDescriptor(o, "transferName");
console.log(result); //Object
for (let name in result) {
    console.log(name, result[name]);
}
//get function transferName(){return this.name} 
//set function transferName(value){this.name = name} 
//enumerable True
//configurable True

设置属性的特性

Object.defineProperty()方法:


let o = {
    name: "Oliver",
    get transferName(){return this.name},
    set transferName(value){this.name = name}
};
let result = Object.getOwnPropertyDescriptor(o, "name");
console.log(result); //Object
for (let name in result) {
    console.log(name, result[name]);
}
//value Oliver
//writable True
//enumerable True
//configurable True
Object.defineProperty(o, "name", {
    value: "Oli",
    writable: false,
    enumerable: false,
    configurable: false
});
let result1 = Object.getOwnPropertyDescriptor(o, "name");
console.log(result1); //Object
for (let name in result1) {
    console.log(name, result1[name]);
}
//value Oli 
//writable False 
//enumerable False 
//configurable False 

该方法不能修改继承属性

设置多个属性特性

Object.defineProperties()方法:

语法:Object.defineProperties(Object, props)


var obj = {};
Object.defineProperties(obj, {
    x: {value: 1, writable: false, enumerable: true, configurable: false},
    y: {get: function(){return this.x}, enumerable: true, configurable: false}
});
console.log(obj.y); //1
console.log(obj.x); //1
obj.x = 2;
console.log(obj.x); //严格模式下报错

老式API

在ES5之前,需要用到

  • __lookupGetter()__

  • __lookupSetter()__

  • __defineGetter()__

  • __defineSetter()__

7 对象的三个属性

  • 原型(prototype)

  • 类(class)

  • 可扩展性(extensible)

7.1 原型属性

对象的原型属性是用来继承属性的


var obj = {};
console.log(obj.constructor); //function Object(){ [native code] }
console.log(obj.__proto__); //Object
console.log(Object); //function Object(){ [native code] }
console.log(Object.prototype); //Object
console.log(Object.prototype.isPrototypeOf(obj)); //True

检测一个对象是否是另一个对象的原型

isPrototypeOf()方法


var obj = {};
var anotherObj = Object.create(obj);
console.log(Object.prototype.isPrototypeOf(obj)); //True
console.log(obj.isPrototypeOf(anotherObj)); //True

7.2 类属性

是一个字符串,用以表示对象的类型信息,默认的toString()方法很有可能被修改,所以应该使用下面的classof函数:

查询类

使用classof()函数:


function classof (o) {
    if (o === null) {
        return "Null";
    }
    if (o === undefined) {
        return "Undefined";
    }
    return Object.prototype.toString.call(o).slice(8, -1);
}

例如:

console.log(classof(obj)); //Object
console.log(classof(Number)); //Function
console.log(classof(123)); //Number

7.3 可扩展性

可扩展性表示是否可以给对象添加新属性

设置为不可扩展,检测是否不可扩展

  • Object.preventExtensions()设置为对象不可扩展

  • Object.isExtensible()检测是否可扩展


var obj = {
    name: "Oliver"
};
Object.preventExtensions(obj);
obj.name = "Oli"; //可修改属性的值
delete obj.name; //可配置属性
obj.age = 18; //不可扩展 严格模式下报错

设置为不可扩展且不可配置,检测是否不可扩展且不可配置

  • Object.seal()

  • Object.isSealed()


var obj = {
    name: "Oliver"
};
Object.seal(obj);
obj.name = "Oli"; //可修改属性的值
delete obj.name; //不可配置属性 严格模式下报错
obj.age = 18; //不可扩展 严格模式下报错

设置为不可扩展、不可配置且所有数据属性设置为只读(setter不受影响),以及检测方法

  • Object.freeze()

  • Object.isFrozen()


var obj = {
    name: "Oliver",
    anotherObj: {
        name: "Oliver"
    },
    set setName (value) {
        this.name = value;
    }
};
Object.freeze(obj);
obj.anotherObj.name = "Oli"; //可以修改属性值为对象的子对象的属性
obj.setName = "Oli"; //不可修改setter属性的值
obj.name = "Oli"; //不可修改属性的值
delete obj.name; //不可配置属性 严格模式下报错
obj.age = 18; //不可扩展 严格模式下报错

8 序列化对象

  • 对象序列化(serialization):将对象的状态转换为字符串,或将字符串还原成对象;

    • JSON.stringify()

    • JSON.parse()

  • JSON(JavaScript Object Notation):JavaScript对象表示法;


var date = new Date();
console.log(date.toString()); //与JSON.stringify()的返回值不同
console.log(date.toJSON()); //与JSON.stringify()的返回值一样

9 对象方法

  • toString方法

  • toLocaleString方法

  • toJSON方法(严格意义上不算对象原型的方法)

  • valueOf方法(用在需要将它转换成某种原始值而非字符串的时候)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 字符串对象是JavaScript中的一种数据类型,用于表示文本数据。字符串对象可以包含任何字符,包括字母、数字、符号和空格等。在JavaScript中,字符串对象是不可变的,也就是说一旦创建就不能修改。但是可以通过一些方法来操作字符串对象,如拼接、截取、替换等。常见的字符串方法有concat()、slice()、replace()等。掌握字符串对象的使用可以帮助我们更好地处理文本数据。 ### 回答2: JavaScript字符串对象是一个在JavaScript中非常重要的事物。JavaScript字符串对象可以帮助我们在JavaScript编程中进行文本操作。通过了解字符串对象,可以使我们更有效地处理字符串数据,并让我们的代码更加强大。 JavaScript中的字符串对象具有很多方法和属性,可以帮助我们对字符串进行各种操作。以下是一些常用的字符串对象方法: 1. length属性:返回字符串的长度。 2. charAt()方法:返回指定索引位置的字符。 3. concat()方法:连接两个或多个字符串。 4. slice()方法:提取字符串的一部分,并返回一个新字符串。 5. substr()方法:从指定位置开始提取长度为指定的字符。 6. replace()方法:替换字符串中的指定文本。 7. split()方法:将字符串转换为数组。 8. toLowerCase()方法:将字符串转换为小写。 9. toUpperCase()方法:将字符串转换为大写。 在JavaScript中处理字符串非常重要,因为在处理表单、验证用户输入等方面都需要使用到字符串。字符串对象也是最常用的JavaScript对象之一,因此熟悉JavaScript字符串对象将有助于提高程序的效率和简洁性。 需要特别注意字符串是不可修改的,一旦创建了一个字符串对象,就无法修改它的值。所以,任何字符串的修改操作都将返回一个新的字符串。 在编写程序时,应根据需要选择适当的字符串操作方法和属性。例如,在向用户显示错误消息时,可能需要使用charAt()方法或slice()方法来提取并显示错误消息中的第一个字符或前几个字符。或者,在对用户输入进行验证时,可以使用indexOf()方法或search()方法来检查输入的字符串中是否包含特定的字符或字符串。 总之,JavaScript字符串对象是处理JavaScript编程中文本数据的重要工具。通过了解字符串对象的各种方法和属性,可以更加有效和灵活的处理和操纵字符串数据。 ### 回答3: JavaScript中的字符串对象是一个字符串值的表示。它提供了对字符串值的访问和操作。JavaScript字符串是Unicode字符串,因此它们可以包含任何Unicode字符(包括多字节字符)。 字符串对象的主要方法有: 1. charAt()方法-返回指定索引的字符。该索引是基于零的。例如: var str = "hello world"; console.log(str.charAt(1)); //输出e 2. concat()方法-将一个或多个字符串连接到原始字符串,并返回新字符串。例如: var str1 = "hello "; var str2 = "world"; var newStr = str1.concat(str2); console.log(newStr); //输出hello world 3. indexOf()方法-返回第一个匹配的字符索引。如果没有找到匹配项,则返回-1。例如: var str = "hello world"; console.log(str.indexOf("world")); //输出6 4. lastIndexOf()方法-返回最后一个匹配的字符索引。如果没有找到匹配项,则返回-1。例如: var str = "hello world"; console.log(str.lastIndexOf("l")); //输出9 5. replace()方法-替换字符串中的字符。例如: var str = "hello world"; console.log(str.replace("world", "everyone")); //输出hello everyone 6. slice()方法-从字符串中提取指定的字符。例如: var str = "hello world"; console.log(str.slice(0, 5)); //输出hello 7. split()方法-将字符串拆分为子字符串,并返回一个数组。例如: var str = "hello world"; console.log(str.split(" ")); //输出["hello", "world"] 字符串对象是JavaScript中最常用的对象之一。它提供了许多方法,可以让您对字符串执行各种操作,包括搜索、提取和更改字符。熟练掌握这些方法,可以使您在JavaScript中更有效地处理字符串值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值