掌握Javascript(三)

本文介绍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中的数组。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注