看懂《书源规则:从入门到入土》(6)JS入门-对象及数据



前言:在前面章节中 ,我们其实接触了一些对象类型和它的一些操作。下面,我们谈谈js里面的对象类型以及不同对象类型的属性和方法。



免责声明:

该系列(看懂《书源规则:从入门到入土》)图文仅供学习使用,自行编写的规则所造成的后果请自行承担,本人概不负责。



开篇前先给耐心等待我更新的酷友道个歉,因为临时的工作原因导致可以用于码字的时间减少,加之本文篇幅也长。所以鸽了很久。真的不好意思。

-------------------

面向对象编程?该怎么通俗易懂的解释呢 汗

这样吧 受虐滑稽 ,现在你有一个妹子(对象,object)但它不会主动和你交流。那么你就只能选择主动出击了 受虐滑稽

出击的方法有两种:一种是属性(properties),一种是方法(methods)。

属性就是你希望获取到对象提供什么信息。方法就是你希望对象进行什么操作。

写代码的时候就这样写:

对象.属性

或者

对象.方法(参数)



比如说:妹子提供了一个叫身高的属性供我们读取,那么我们这样写:

妹子.身高

就获得了她的身高。



又比如说:妹子提供了一个叫看的方法供我们调用,可以指定一个要看的东西,那么我们这样写:

妹子.看(黑板)

就能让她去看黑板。



那么怎么知道妹子从黑板上看到了什么内容?这样:

妹子.看(黑板).内容

前面妹子看黑板的时候,就产生了一个新对象就是看到的东西。然后再从这个对象里获取看到的内容 受虐滑稽

也许上面的代码不是那么优雅,尤其是代码老长老长的时候 受虐滑稽 ,那么可以这样:

var blackboard=妹子.看(黑板)

blackboard.内容

先把 妹子.看(黑板) 所产生的对象储存到一个变量里,然后再读这个变量的 内容 这个属性。

--------------

世界上有80亿人,但总的来说只分两种:男人和女人 受虐滑稽

js也一样,你可以创建无数个对象(理论值。实际还是有硬件限制),但对象的类型只有那么几个 受虐滑稽

基本类型:Undefined(未定义)、Null(空)、Boolean(布尔值)、Number(数值)、String(字符串)

引用类型:Object(对象)、Array(数组)、Function(函数)、RegExp(正则表达式)......

请注意:ECMASCRIPT标准一直在升级,以上为保证兼容性仅列举常用的类型 !更多内容详见MDN( 查看链接 )



什么叫基本类型?这么理解吧:道生一,一生二,二生三,三生万物。基本类型就基本在,它们是数据最底层的表示形式。

比如说你可以在一个数组里放很多个数据,但你不能在一个数值里放很多个数据,哪怕是一个很大的数字,那也只是一个数据而已 受虐滑稽

捂脸 请原谅我语文不好,真不知道该怎么解释 捂脸

--------------------

既然解释不好就不解释了,开干! 受虐滑稽

Undefined:这个类型就只有一个值undefined,表示相应的值未设定。比如说:

var x

这个时候我们没有给变量x赋任何值,所以此时它的值是undefined。

----------

Null:这个类型只有一个值null,表示一个空值。

怎么理解Undefined和Null呢?Undefined就表示不知道它是一个什么东西,Null就表示它没有任何东西。

----------

Number:数字,表示一个IEEE 754标准的双精度64位浮点数(具体有多大自己去查,反正你用不完 受虐滑稽 )。还有两个特殊值NaN(No a Number,不是一个数字)和Infinity(无穷大)

Number对象的属性和方法。

请注意,这几个是Number对象的静态属性/方法,的调用方法并不是创建一个对象后调用使用(什么叫创建后调用看我上面“面向对象”的例子 受虐滑稽 )。看着图中照抄就是了 受虐滑稽



下面3个方法就是可以对数字对象调用了。

具体用例看图中示例

---------

Boolean:布尔,只有两个值true和false。表示逻辑“真”或“假”

----------

String:字符串,表示一堆utf-16字符的有序集合(其实像emoji这样的utf-16扩展字符也是支持的,不过最好别这么干 。因为涉及到Surrogate Pair编码,处理的时候容易出错)。创建字符串时用英文双引号或单引号括着,注意单引号优先级比双引号高!

比如

var x="JavaScript"

var x='JavaScript'

这两种方式都可以把字符串 JavaScript 赋值给变量x。

玩个梗 var x='""' 可以把两个双引号这个字符串赋值给变量x 受虐滑稽



字符串可以使用加号/加赋值运算符进行拼接

示例:

var x="fsxi"

var y="tutu"

那么 x+y 将得到字符串fsxitutu,x+=y 将使变量x的值变成fsxitutu



为符合题意,涉及字符串的操作将是本图文重点,可能有亿点长请见谅 捂脸

----

各位还记得之前讲过的转义吗?没错,在字符串里也能玩! 哈哈哈

\0:NULL符(\u0000)

\':一个单引号

\":一个双引号

\\:反斜杠

\n:换行符

\r:回车符

\v:垂直制表符

\t:水平制表符

\b:退格符

\f:换页符

\uHHHH:一个utf-16字符,H表示任意16进制数字。

\xHH:一个ASCII字符,H表示任意16进制数字。

----

温馨提示:以下所有对字符串操作的方法均不会修改原字符串,而是返回一个新对象。



String对象的静态方法:

String.fromCharCode():

从指定的utf-16码值创建字符串,括号里可以是多个0-65535的数字,用逗号隔开。

比如String.fromCharCode(65,66,67)就会返回一个字符串ABC



String.fromCodePoint():

从指定的代码点序列创建的字符串,和上面类似但括号里可以是容纳0-1114111的数字。

----

String对象属性:

length:返回字符串的字符数。注意上面提到的扩展字符问题,字符编码大于65535的会以两个字符表示!!!(虽然在外面看只是一个字符,但字符串要用两个字符的空间来表示)

举例:

var x="ABC"

var y="酷安"

var z="💙"

那么 x.length 返回3,y.length返回2,z.length返回2。

----

String对象的方法:

charAt(num):返回字符串指定位置的字符,位置从0开始,不支持负数。注意扩展字符问题(下同。如无特殊说明均需注意此问题)

charCodeAt(num):返回字符串指定位置字符的编码,位置从0开始 ,不支持负数。

codePointAt(num):返回字符串指定位置字符的编码,位置从0开始,不支持负数。该方法支持扩展字符,所以不需要考虑扩展字符问题。



indexOf(str , num):查找str在字符串中在num指定的位置后首次出现的位置。

位置从0开始,不支持负数(该参数留空默认为0)。

返回被查找到的子字符串首个字符的位置。

示例:

var x="fsxitutu"

那么 x.indexOf("tu") 返回4,x.indexOf("tu",5) 返回6。

lastIndexOf(str , num):查找str在字符串中在num指定的位置前最后出现的位置。

位置从0开始,不支持负数(该参数留空默认为0)。

返回被查找到的子字符串首个字符的位置。



startsWith(str , num):判断在字符串中num指定的位置后是否以str开头。

位置从0开始,支持负数(该参数留空默认为0)。

返回判断结果(布尔值)

示例:

var x="fsxitutu"

那么 x.startWith("xi") 返回false,x.startWith("xi",2)返回true。

endsWith(str , num):判断在字符串中num指定的位置前是否以str结尾。

位置从0开始,支持负数(该参数留空默认为字符串的length值)。

返回判断结果(布尔值)

示例:

var x="fsxitutu"

那么 x.endsWith("tu") 返回true,x.endsWith("xi" , 4) 返回true。

includes(str):判断字符串是否包含str子字符串。

返回判断结果(布尔值)



split([str|reg] , num):使用指定的字符串/正则表达式将字符串分割成字符串数组。

可限制数组最大为num个值(留空表示不限制长度)。

用于作为分隔符的字符串/匹配正则表达式的字符串不会被包含到数组中

返回分割出的数组。

如果str="" (空字符串),则将用每个utf-16字符之间的空隙作为分隔符,即返回的数组每一个元素都是单个utf-16字符(请注意扩展字符问题!该操作将破坏Surrogate Pair代理对!)

如果str留空,则将整个字符串作为数组的一个元素,即返回的数组只有一个元素就是整个字符串。



slice(num1 , num2):返回num1位置到num2位置之间的字符串。

包含num1位置的字符但不包含num2位置的字符。

参数支持负数,若num1>num2返回空字符串。

num2留空默认字符串length值。

substring(num1 , num2):和上面一样 受虐滑稽

substr(num1 , num2):返回num1位置开始向后num2个字符组成的字符串。

包括num1位置的字符。

num1支持负数;num2留空表示读到结尾。



match(str/reg):使用指定的正则表达式在字符串中匹配。

返回匹配到的子字符串数组。

如果参数为字符串而不是正则表达式,相对于使用简单正则表达式匹配。

示例:

var x="fsxitutu"

那么 x.match(/tu/) 返回 ["tu"] ,x.match(/tu/g) 返回 ["tu","tu"]

x.match("tu") 相对于 x.match(/tu/) 返回 ["tu"]

replace(str|reg , str):返回一个把字符串中匹配正则表达式的子字符串替换成指定字符串的新字符串。

示例:

var x="fsxitutu"

那么 x.replace(/xi/ , "XI") 返回 "fsXItutu"

search(str|reg):返回匹配指定正则表达式的子字符串在字符串中首次出现的位置(子字符串首字符的位置)。

如果匹配不到返回 -1



toLowerCase():返回把字符串中所有大写英文字母转换成小写的新字符串。

示例:

var x="fsxiTUTU"

那么 x.toLowerCase() 返回 "fsxitutu"

toUpperCase():返回把字符串中所有小写英文字母转换成大写的新字符串。



repeat(num):重复字符串num次并返回。

如果num为0将返回空字符串。

示例:

var x="a"

x.repeat(0) 返回 ""

x.repeat(1) 返回 "a"

x.repeat(2) 返回 "aa"



trim():返回去除字符串开头和结尾的空字符后的字符串。(什么叫空白字符以前讲过,不再赘述)

trimStart():返回去除字符串开头的空字符后的字符串。

trimEnd():返回去除字符串结尾的空字符后的字符串。

---------

Object:对象。以 键:值 对的方式存储数据。JavaScript中所有的类型都是这货的子类型 受虐滑稽 。什么叫键:值对,举个例子:

"fsxitutu"

这里,我们创建了一个数据,他的类型是string,值是fsxitutu。但很显然,我们没有办法在其他地方调用这段数据。那么该怎么调用?还记得我们之前的操作吗?

var x="fsxitutu"

这样,我们在其他地方通过x这个变量就可以调用到这个数据了。这里的x就是这段数据的“键”(key),fsxitutu就是这段数据的“值”(value)。当我们使用x这个键的时候,js解释器就会去内存里找x这个键指向的数据并返回。

----

扯了那么多,这个类型该怎么玩?

这是一个object类型的数据:

{x:"fsxitutu"}

现在,他有一个属性叫 x ,属性x的值是"fsxitutu"(字符串fsxitutu)。

{x:"fsxitutu"}.x

这样,我们就能读出"fsxitutu"了。

当然,我们也可以把他赋值给一个变量:

var y={x:"fsxitutu"}

那么我们就可以用 y.x 或者 y["x"] 读出y这个对象的x属性了

也可以用 y.x=xxx 或 y["x"]=xxx 去给y的x属性重新赋值

(请注意,用后一种方式的话中括号里的属性名一定要用引号括起来,不然会被视为变量进行解析!)



这个类型一般是用于储存和传递数据。比如一些恶心的网站会用JSON(JavaScript Object Notation),传递一大坨数据,然后用canvas把网页画出来 流汗滑稽 流汗滑稽 流汗滑稽

(题外话:我挺鄙视这种行为的,纯属是屠龙者终成恶龙了 t耐克嘴 t耐克嘴 t耐克嘴 )

---------

Array:数组。别被名字迷惑了,这货不止能放数字 流汗滑稽 。和上面的object类似,不过数组里的数据没有key来索引,只能通过数据在数组里的位置(从0开始)来索引。

示例:

var x=["a","b"]

这里,声明了一个数组 ["a","b"] 并把他赋值给了变量x。那么,我们要怎样操作其中的元素呢?这样:

数组变量名[位置]

比如 x[0] 这样就可以读到例子中的数组第一个元素,当然,也可以用赋值运算符去改写。

----

Array对象属性:

length:返回数组的长度。如果对数组的该属性赋值将会将数组截断到指定的长度,多余部分将丢弃!!!



Array对象方法:

concat(arr......):连接多个数组,返回连接出来的数组。

示例:

var x=[1,2]

var y=[3,4]

var z=[5,6]

那么 x.concat(y,z) 返回 [1,2,3,4,5,6]



join(str):将数组中的元素合并成一个字符串,使用str指定的字符串作为元素间的分割符(留空默认是","(英文逗号))

示例:

var x=[1,2]

x.join()返回字符串 1,2



push(obj1 , obj2......):向数组末尾加入一个至多个元素,返回新数组的长度。此方法会修改原数组

示例:

var x=[1,2]

x.push(3) 返回 3 ,此时变量x的值是 [1,2,3]

unshift(obj1, obj2......):向数组开头加入一个至多个元素,返回新数组的长度。此方法会修改原数组



pop():删除数组最后一个元素,返回被删除的元素。此方法会修改原数组

shift():删除数组第一个元素,返回被删除的元素。此方法会修改原数组



splice(num1 , num2 [, obj......]):从数组num1位置(包含)删除num个元素,并插入指定的元素(可选)

返回被删除元素组成的数组。此方法会修改原数组



slice(num1 , num2):返回数组num1位置到num2位置之间的子数组。包含num1不包含num2。

num1留空默认为0,num2留空默认数组的length值

num1、num2支持负数

at(num):返回数组指定位置的元素。和 数组[位置] 这种传统方式不同的是at方法支持负数 受虐滑稽



reverse():把数组内的元素反向排序。返回新的数组,此方法会修改原数组

flat(num):把数组按指定深度展开。参数留空默认是1。返回展开后的新数组



indexOf(obj):从左向右在数组里查找指定的元素,返回该元素的位置。如果找不到返回-1

lastIndexOf(obj):从右向左在数组里查找指定的元素,返回该元素的位置。如果找不到返回-1

---------

请注意:和大部分编译型编程语言不同。js的Object和Array类型是不限长的,所以可以随时加入新属性/新元素,操作方法:

Object:object对象.属性名 或 object["属性名"]

Array:array对象[位置]

---------

Function:函数。事先封装好以便调用的一段代码。

举个例子:如果要在脚本里的几个不同位置调用同样的一段代码,应该怎么做?复制粘贴几次?

又或者,把这段代码封装成一个函数,在需要的地方直接 函数名() 这样调用 受虐滑稽



函数的声明方式很简单

function 函数名(参数列表){代码}

比如说:

function sum(x,y){console.log(x+y)}

这样,就声明了一个叫sum的函数,它默认接受两个参数。

调用后内部会声明x和y两个局部变量,把第一个接受的参数值赋值给x,第二个赋值给y。

执行的代码是向控制台日子输出x+y的值。



函数默认的返回值是undefined如果要返回其他值可以在函数里用

return 值

的方式设置返回值。注意:执行到return后函数会停止执行后续代码并返回指定的值!

---------

RegExp:正则表达式。怎么声明怎么使用看前面的文章! t耐克嘴

RegExp对象方法:

exec(str):返回指定字符串中匹配正则表达式的子字符串数组,如果匹配不到返回null

test(str):测试字符串中能否有子字符串被正则表达式匹配到。返回布尔值

--------------------

结语&真心话&预告:

本章涉及内容太多了,常用的我能说也说了,难理解的我也是尽量举例了。

至于什么闭包,匿名函数,构造函数/字面量/eval,“一行代码”......这种不利于代码维护的东西我是不会去说的,请不要在评论区/私信问我怎么写,要学自己看MDN去,其它问题我会乐于解答的(如果工作之余有空闲的话)。好代码不止要电脑看得懂也要其他人看得懂,规范化的代码写起来舒服看起来也舒服 哈哈哈

说实话,写文章的过程也是一个温故而知新的过程。自己有什么不足平时可能看不出来但在倒墨水的时候就一览无遗了。

下章应该就是终章了。语法差不多也说完了,下面应该就要通过 【阅读】 提供的api接口来和阅读进行交互了。

有什么意见和建议欢迎提出来。