脚本宝典收集整理的这篇文章主要介绍了

JS-对象

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

一、概述

JS是一种面向对象的语言。除了基本数据类型number, string, boolean(true, false), null, undefined,其他的都是对象。对象就是一个"name-value"对集合。

二、操作对象

2.1 创建对象

JS有三种创建对象的方式:字面量,Object.create,new构造方式。

2.1.1 Object.create(null | object)

严格来说调用Object.create方法是创建JS对象的唯一方式(其他两种方式内部实现都是基于该方法的)。该方法功能是创建一个对象,并且该对象的原型指向create的参数对象。
参数:必须是null或者对象,否则报错。null表示创建一个没有原型的空对象。

var p = { a: 1}; // 对象字面量
var c1 = Object.create(p); // 对象c1的原型指向p
var c2 = Object.create(null);// 对象c2没有原型

clipboard.png

2.1.2 对象字面量

对象字面量是一种创建对象的便捷方式,见上例。其中对象p的创建方式就是对象字面量。JS解释器会对它进行处理的,等价于:

var p = Object.create(Object.prototype);
p.a = 1;

所以说对象字面量内部也是通过Object.create方式创建对象的,并且所有对象字面量方式创建的对象的原型都执行Object.prototype(如上图)。

思考:JS解释器如何区分语句块花括号{}和空对象花括号{}的?
先看看这两条语句执行的结果?

{} + [] // 0
[] + {} // "[object Object]"
  1. {}作为右值(赋值表达式右侧),实参,在运算符的右侧,被括号()包裹则作为对象,其他则视为语句块:
    下面输出都是:"[object Object]"

    console.log({} + []) // 作为实参了
    
    ({}) + [] // 被括号包裹
    
    var a = {} + [] //作为右值
    console.log(a) 
  2. 我们知道当ES6箭头函数的函数体只有一条语句时可以省略语句块花括号,但是如果箭头函数返回的是一个对象该如何书写呢?

    var func1 = () => {age: 12} // 本意是想返回对象{age:12},显然这样写就不对了,花括号会被作为语句块解析
    var func2 = () => ({age: 12}) // 可以用括号包裹下
    var func3 = () => { return {age: 12}} // 或显示的写全

2.1.3 new构造方式

JS的作者为了讨好类语言的开发者,引入了第三者创建对象方式,即new构造方式。这使得JS对象的创建有点像类语言的对象创建。

1) 格式
new关键字 + 空格 + 函数名字 + [(参数)]

其中参数是可选的,当没有参数传递时,可以省略括号。如:

function Func(){}
var c1 = new Func();
var c2 = new Func; // 如果没有参数传递,可以省略括号。
function Func(name){
  this.name = name;
}
Func.prototype.say = function(){
};
var c = new Func('q');

clipboard.png

2) 内部原理

这种方式的内部也是通过Object.create方式构建的。new方式创建对象大致分为三步:
Step1:创建一个对象A,并且对象A的原型指向构造函数的prototype属性
Step2:以对象A绑定到构造函数上调用构造函数
Step3:如果构造函数返回值不是个非null的对象,则返回构造函数的返回值作为new表达式的值,否则以对象A作为new表达式的值。

function Func(name){
  this.name = name;
}
Func.prototype.say = function(){
};
function create(){ // 模拟new操作符
  var func = arguments[0];
  var args = Array.prototype.slice.call(arguments, 1);
  var other = Object.create(func.prototype); // Step 1
  var result = func.apply(other, args); // Step 2
  return typeof result === 'object' && result ? result: other; // Step3 注意返回值
}
var c = create(Func, 'q');

2.2 访问对象属性

访问方式也就是get/set/delete。在get访问中会涉及原型链,set/delete访问不会。

var Obj = {
  name: 'john'
};
// Get操作
var n = Obj.name; // 等价var n = Obj["name"];
// Set操作
Obj.age = 12; 

2.2.1 Get操作流程:

clipboard.png

2.2.2 Set操作流程:

clipboard.png

2.2.3 delete操作

可以通过delete操作符删除对象的属性,只能删除对象本身的属性。

var p = {
  age: 26
}
var obj = Object.create(p);
obj.name = 'john';
console.log(obj.name); // john
console.log(obj.age); // 26
delete obj.name; // 删除属性
delete obj.age; // 删除属性
console.log(obj.name); // undefined
console.log(obj.age); // undefined

clipboard.png

2.3 引用对象

JS中对象是引用类型的。对象在作为值时,是作为引用传递的。

var a={}, b={}; // a,b分别指向不同的对象
var c = d = {}; // c,d指向同一个对象

三、反射

确定对象的类型有时很有必要。

3.1 typeof 操作符

通过typeof操作符可以获取值的类型:

console.log(typeof 1); // number
console.log(typeof ''); // string
console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log(typeof true); // boolean
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function(){}); // function

但是发现这种方式中null, 数组也都是返回“object”。原因是JS中没有原生数组类型,数组是通过对象模拟的,所以数组也是对象。但是如何区分数组和对象呢???

3.2 Object.prototype.toString

typeof是有缺陷的,在实际应用中常通过Object.prototype.toString方法确定对象类型的。

console.log(Object.prototype.toString.call(1)); // [object Number]
console.log(Object.prototype.toString.call('')); // [object String]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
console.log(Object.prototype.toString.call( {})); // [object Object]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(function(){})); // [object Function]

看例子中输出结果中发现不同之处了吧。假如判断对象是否为数组:

var isArray = function(val){
  return Object.prototype.toString.call(val) === '[object Array]';
}

目前的很多库zeptojs,underscorejs中都是这样实现的。

总结

以上是脚本宝典为你收集整理的

JS-对象

全部内容,希望文章能够帮你解决

JS-对象

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过