本文介绍Javascript中对象的相关知识。
对象基本知识
高度关联的变量放在一起,就构成了对象。
对象里可以包括各种类型,比如String,Number,甚至包含对象,以及函数对象、数组对象等。
const circle = {
radius:1,
location:{
x:1,
y:1
},
isVisable:true,
draw:function(){
console.log(‘draw’);
},
// 函数对象
};
circle.draw();
// 调用circle.draw(),对象内draw称方法,在对象外则叫函数。
工厂函数
如果有多个类似的对象,需要复制多遍,所以就出现了工厂函数和构造函数,本节先介绍工厂函数。
function createCircle(radius){
return {
radius,
// 等价于 radius:radius
draw(){
console.log(“draw”);
}
// 等价于 draw:function(){…}
};
}
建好工厂函数后,可以调用它来创建对象:
const circle1 = createCircle(1);
console.log(circle1);
// 输出{radius: 1, draw: ƒ}
const circle2 = createCircle(2);
console.log(circle2)
// 输出{radius: 2, draw: ƒ}
构造函数
这是创建对象的另一种方法。
前面讲过,变量用驼峰命名法,它是第一个单词小写,后面单词首字大写,类似
oneTwoThreeFour
构造函数使用帕斯卡命名法,所有单词首字大写,类似
OneTwoThreeFour
下面看代码:
function Circle(radius) {
// 注意命名是首字大写
this.radius = radius;
// this表示指向自己
this.draw = function () {
console.log(‘draw’);
}
}
// 下面创建对象
const circle = new Circle(1);
// 使用new关键字创建对象
* 构造函数与工厂函数,无所谓哪个好哪个不好,看个人喜好。
C#、Java程序员可能因为习惯更喜欢构造函数,而无经验的开发者或许更喜欢工厂函数。
对象的动态特性
Javascript对象是动态的,可以动态添加属性和方法,以及删除已有成员。
const circle = {
radius: 1,
}
// 添加属性和方法
circle.color = ‘Yellow’;
circle.draw = function () { };
// 删除属性和方法
delete circle.color;
delete circle.draw;
有人可能会觉得奇怪,不是定义circle为常量吗?怎么还能修改成员个数。
实际上,circle只是指向地址(引用),里面的成员增删实际不改变它引用的地址。如果再定义 circle={} ,那才会出错提示常量不能修改。
构造器属性
每个对象都有一个构造器属性 constructor,它指向对象的构造函数。
function createCircle(radius) {
return {
radius,
draw: function () {
console.log(“draw”);
}
}
}
const circle = createCircle(1);
// 用工厂函数创建对象circle
function Circle(radius) {
this.radius = radius;
this.draw = function () {
console.log(“draw”);
}
}
const another = new Circle(1);
// 用构造函数创建另一对象another
console.log(another.constructor);
// 能看到它指向构造函数Circle(radius)
console.log(circle.constructor);
// 而用工厂函数创建的对象的构造函数是Object()
// ƒ Object() { [native code] }
Javascript对象有内置构造函数,如:
- new String(),当然一般直接用 ” 或 “”
- new Boolean(),当然一般直接用 true,false
- new Number()
函数也是对象
函数也是对象,可以查看函数的各个属性
function Circle(radius) {
this.radius = radius;
this.draw = function () {
console.log(“draw”);
}
}
console.log(Circle.name);
// 输出Circle
console.log(Circle.length);
// 输出 1,表示属性的个数
// 看一个有意思的,我们查下函数的构造函数
console.log(Circle.constructor)
// ƒ Function() { [native code] }
// 表示函数的构造函数都是Function()
从上面我们知道函数的构造函数是Function(),我们再用这个构造函数创建一个新函数Circle1。
const Circle1 = new Function(‘radius’, `
this.radius=radius;
this.draw=function(){
console.log(‘draw’);
}
`);
// 我们用函数的构造函数Function()创建了函数 Circle1,
// 它的参数是radius,函数体包在“里
// 接着,我们可调用了
const circle = new Circle1(1);
用new关键字使用构造函数,javascript的过程大致这样的:
新建一个空对象,传给call函数,再给出实参。
const ob = {}
Circle1.call(ob, 3);
// 等同于ob = new Circle1(3)
如果不用new关键字,javascript将不新建空对象,而是指向全局对象window.
如:
const another = Circle(1);
// 注意没有加关键字 new
// 等同于
Circle.call(window,1)
与call()方法类似,还有一个apply()方法,他不用一个个传入实参,可以传入实参数组。
Circle.apply({}, [1, 2, 3])
值类型和引用类型
前面讲过,javascript包括值类型和引用类型。
值类型有:
- Number
- String
- Boolean
- Symbol,ES6新增类型
- undefined
- null
引用类型有:
- Object
- Function
- Array
值类型复制的是值。
引用类型复制的是它的地址,复制的变量修改内容将影响原有值。
枚举对象成员
对象不是一个可枚举的类型,不能使用for…of来遍历,比如使用:
const circle = {
radius: 1,
draw() {
console.log(‘draw’);
}
};
for (let key of circle) { }
// 将提示如下错误:
// Uncaught TypeError: circle is not iterable
我们改成:
for (let key of Object.keys(circle))
console.log(key);
// 或
for (let entry of Object.entries(circle))
console.log(entry)
Object是大括号创建的对象的构造函数。下面两句是等价的:
let x = {};
let x = new Object();
检查是否在对象内:
if (‘radius’ in circle) console.log(‘yes’)
对象遍历要用 for…in结构
for (let key in circle) console.log(key, circle[key])
克隆对象
源对象:
const circle = {
radius: 1,
draw() {
console.log(‘draw’);
}
};
有三种方法进行克隆:
1:
const another = {}
for (let key in circle)
another[key] = circle[key]
// 这种方法很古老
2:
const another = Object.assign({}, circle)
// 不一定要给assign传空对象,如果已有的对象,
// 则将circle加到已有对象之上
3:
const another = { …circle }
// 三个点 … 相当于将所有成员解析出来,再赋于another
垃圾回收
现代语言都会有垃圾回收机制:找出不用的变量,然后回收分与给他们的内存。
回收是自动运行的,无法控制。
Math对象
内置对象Math,可以google下 javascript math 查看详细用法。
涉及数学方面的可以试一下是否用得上。
console.log(Math.round(1.9))
// 2
console.log(Math.max(1, 2, 3, 4, 5))
// 5
console.log(Math.random())
// 输出0-1之间的一个随机数
String对象
内置对象String,搜索google,关键字“javascript String”学习下。
JavaScript有两种类型的字符串,一种是值类值,一种是String对象。
1.
const message = “hi”
// 这是值类型,查看其类型是 string
console.log(typeof (message))
2.
const another = new String(‘hi’)
console.log(typeof (another))
// 这是对象类型 object
但是对值类型的message也可以调用replace()等方法,因为系统会自动值类型转换成对象类型。
加上反斜杠 \ 表示转义字符。如
\’
\”
\n
等。
字符串的拆分:
message.split(“”)
模板语法
ES6有模板语法,用反引号 ` (键盘1左边的字符)
主要好处是可以不用转义字符,而且比较清晰,对于输入邮件正文类似的很有用。
const message = `
This is my
‘first’ message
`
还可以用${}表示变量或表达式。
const name = ‘John’
const message =
`Hi ${name} ${2 + 3}
Thank you!
`
console.log(message)
// 输出
// Hi John 5
// Thank you!
Date对象
内置对象,具体用法可查找google,“JavaScript Date”。
const now = new Date()
// Wed Aug 18 2022 00:15:19 GMT+0800 (中国标准时间)
now.setFullYear(2021)
// Wed Aug 18 2021 00:15:19 GMT+0800 (中国标准时间)
const date1 = new Date(‘May 11 2022 09:00’)
// Wed May 11 2022 09:00:00 GMT+0800 (中国标准时间)
const date2 = new Date(2022, 4, 11, 9)
// Wed May 11 2022 09:00:00 GMT+0800 (中国标准时间)
// 注意月份4代表5月,从0开始
console.log(now.toDateString())
// Wed Aug 18 2021
console.log(now.toTimeString())
// 00:15:19 GMT+0800 (中国标准时间)
console.log(now.toISOString())
// 2021-08-17T16:15:19.798Z
小结
本文介绍了Javascript中对象的相关知识,下一篇计划介绍javascript中的数组。