JavaScript 对象基础

1. 什么是 Object 对象?

JavaScript 中的所有事物都是对象,如:字符串、数值、数组、函数等,每个对象带有属性和方法。
对象的属性:反映该对象某些特定的性质的,如:字符串的长度、图像的长宽等;
对象的方法:能够在对象上执行的动作。例如,表单的“提交”(Submit),时间的“获取”(getYear)等;
JavaScript 提供多个内建对象,比如 String、Date、Array 等等,使用对象前先定义。

2. 如何定义对象?
  • 字面量创建法

    var person = {
      name: "Grace",
      age: 18,
      gender: "female"
    };
    
  • 借助 new 操作符 + Object 创建

    var person = new Object();
    person.name = "Grace";
    
    //下面是另一种创建属性的方式
    
    var myHeight = "height";
    var myHeightValue = "163cm";
    person[myHeight] = myHeightValue;
    person.height === person[myHeight]; // true
    
  • 构造函数

    function Person(name, age, gender) {
      this.name = name;
      this.age = age;
      this.gender = gender;
    }
    
    var kitty = new Person("Kitty", 8, "female");
    var grace = new Person("Grace", 18, "female");
    
    kitty.name; // "Kitty"
    grace.age; // 18
    
    Person.prototype.greet = function () {
      return ("Hello, I\'m " + this.name + "!");
    }
    
    grace.greet(); // "Hello, I'm Grace!"
    
    1. 该方法可以利用一个构造函数(new Person(...))来创建很多个对象,并且构造函数中的 this 会在创建的时候,指向新创建的对象,并且默认返回 this,所以在最后就不用 return this 了。

    2. 如果想要给这些对象创建一个新的属性,例如 greet 就只要将这个属性加到他们的原型链上就好了,即 Person.prototype.greet ,这样就可以让他们的 greet 函数都可以共享一个属性,节省内存。

    3. 需要注意的是:

      kitty.greet; // function: Person.greet()
      grace.greet; // function: Person.greet()
      kitty.greet === grace.greet // true
      

      但是如果是下面这样写:(直接写在构造函数里)

      function Person(name) {
        this.name = name;
        this.hello = function () {
          alert('Hello, I\'m ' + this.name + '!');
        }
      }
      
      var kitty = new Person("Kitty");
      var grace = new Person("Grace");
      
      kitty.hello; // function: Person.hello()
      grace.hello; // function: Person.hello()
      kitty.hello === grace.hello; // false
      

      这个时候它们并不是共用一个函数,只不过是函数的名称和内容相同而已,所以实际上是两个不同的函数。

    4. 上面的第一段代码中:

      return ("Hello, I\'m " + this.name + "!");
      

      可以写成:

      return (`Hello, I'm ${this.name}!`);
      

这里主要是参考了廖雪峰前辈主页的创建对象

3. 如何获取对象的值?

通过(.)或者([])来获取,其实在上面创建的时候就有这样的例子了,我们把它单独拎出来:

kitty.name; // "Kitty"
grace["age"]; // 18

var person = {};
var myHeight = "height";
var myHeightValue = "163cm";
person[myHeight] = myHeightValue;
person[myHeight]; // "163cm"
person.height; // "163cm"
person["height"]; // "163cm"

但是按照规范最好用上面两种,不怎么用 person[myHeight] 这样的。

4. Object 对象属性和方法
  • String 对象
    属性如下:(之后的对象前两个属性类似)

    属性名 作用
    constructor 所建立对象的构造函数
    prototype 能够为对象加入的属性和方法
    length 返回字符串的字符长度

    方法如下:

    方法名 作用
    charAt() 返回指定索引位置的字符
    charCodeAt() 返回指定索引位置字符的 Unicode 值
    concat() 连接两个或多个字符串,返回连接后的字符串
    fromCharCode() 将 Unicode 转换为字符串
    indexOf() 返回字符串中检索指定字符第一次出现的位置
    lastIndexOf() 返回字符串中检索指定字符最后一次出现的位置
    localeCompare() 用本地特定的顺序来比较两个字符串
    match() 找到一个或多个正则表达式的匹配
    replace() 替换与正则表达式匹配的子串
    search() 检索与正则表达式相匹配的值
    slice() 提取字符串的片断,并在新的字符串中返回被提取的部分
    split() 把字符串分割为子字符串数组
    substr() 从起始索引号提取字符串中指定数目的字符
    substring() 提取字符串中两个指定的索引号之间的字符
    toLocaleLowerCase() 根据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射
    toLocaleUpperCase() 根据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射
    toLowerCase() 把字符串转换为小写
    toString() 返回字符串对象值
    toUpperCase() 把字符串转换为大写
    trim() 移除字符串首尾空白
    valueOf() 返回某个字符串对象的原始值

(取自菜鸟教程)

总结几个我出过错的方法:

  1. .toString().valueOf()
    这两者的区别:

    • toString()和valueOf()的主要不同点在于,toString()返回的是字符串,而valueOf()返回的是原对象

    • 由于undefined和null不是对象,所以它们toString()和valueOf()两个方法都没有

    • 数值Number类型的toString()方法可以接收转换基数,返回不同进制的字符串形式的数值;而valueOf()方法无法接受转换基数。
      (这个“转换基数”我查了一下,指的是,对于不同进制之间的取值,比如:(19).toString(16) 的值是 "13";而 (19).valueOf(16) 的值还是19

    • 时间Date类型的toString()方法返回的表示时间的字符串表示;而valueOf()方法返回的是现在到1970年1月1日00:00:00的数值类型的毫秒数

    • 包装对象的valueOf()方法返回该包装对象对应的原始值

    • 使用toString()方法可以区分内置函数和自定义函数

  2. .exec() & .match():它们俩都是用来匹配的,不过前者是正则表达式的一个方法,方法可以作用于字符串,后者则相反。

  3. .slice() & .substring():这两个其实作用都是一样的,根据索引值截取字符串。不过有以下特殊情况

    var str = 'hello world';  
    str.slice(-3); // 'rld' 它会从后往前取|index|个字符  
    str.substring(-3); // 'hello world' 它会默认把负数转换成0  
    str.slice(1, -3); // 'ello wo' 这个时候,负数会转换成(string.length - |index|)  
    str.substring(1, -3); // ‘h’ 和前面一样,会将负数转换成0  
    //但是上面这个转换之后是 (1, 0),只有 substring 是可以取到字符串,slice 不行。
    str.slice(1, 0); // '' 
    //原因就是 substring 会将更小的索引值当成起始索引位置,而 slice 不行。
    
  4. .localeCompare()
    stringObject.localeCompare(target)
    返回比较结果的数字。如果 stringObject 小于 target,则 localeCompare() 返回小于 0 的数。如果 stringObject 大于 target,则该方法返回大于 0 的数。如果两个字符串相等,或根据本地排序规则没有区别,该方法返回 0。
    这里的大于 target 的比较方法是可以自己设定的,是没有被 ES 标准规定的,默认是按 Unicode 编码顺序的,可以和 .sort() 搭配起来给中英文排序,下面举个例子:

    let comparatorFun = (valueA, valueB) => {
      let targetA = valueA != null && valueA.toString().toLowerCase();
      let targetB = valueB != null && valueB.toString().toLowerCase();
      return targetA != null && targetA.localeCompare 
             ? targetA.localeCompare(targetB) : targetA - targetB;
    }
    
    let array=[1,9,0,'','我','他','我们']
    let sortArray = array.sort((a,b)=>comparatorFun(a,b)) //[ '', 0, 1, 9, '他', '我', '我们' ]
    
  • Number 对象
方法名 作用
valueOf() 返回数学对象的原始值
.toExponential(fractionDigits) 将数字转换为指数表示形式字符串,fractionDigits指定指数的小数位的位数, 取值区间[0,20].
.toFixed(fractionDigits) 将数字表示成10进制字符串, fractionDigits同上.
.toPrecision(precision) 与toFixed()类同, 只是precision指定的是数字的有效位数, 取值范围[0,21].
.toString(radix) 将number转换为需要的进制字符串形式,radix默认是10.

关于 .toFixed() 方法的一个小坑。
我们都知道这是一个四舍五入法保留 n 位小数的一个方法,但是当我们用于 1.toFixed(2) 的时候是会报 Uncaught SyntaxError: Invalid or unexpected token 的语法错误的。但是如果给 1 加上括号的话是成立的。后来是先查了一下这个方法的一个实现机制,它是先取小数点前的整数,然后再对后面的数进行处理大概这个样子。我们就觉得可能和小数点有关,之后我又查了一下,发现也有别人遇到过这个问题,并且总结了一下:

JS 引擎在运行时,默认将 .toFixed() 的点当作是 1.0 的点了,所以就觉得少了一个点,所以会报语法错误的。
解决的办法有很多种:

  1. 给无小数整数加一个括号,与后面的方法隔开。
  2. 在整数后面多加一个小数点即可。
  3. 将整数赋给一个变量,然后通过变量调用该方法。
  4. 给整数加零...

总之就是解决这个语法冲突而已,对于其他的方法,例如 .toString() 也是适用的。

  • Date 对象
方法名 作用
getDay() 返回一周中的第几天(0-6)
getYear() 返回年份.2000年以前为2位,2000(包含)以后为4位
getFullYear() 返回完整的4位年份数
getMonth() 返回月份数(0-11)
getDate() 返回日(1-31)
getHours() 返回小时数(0-23)
getMinutes() 返回分钟(0-59)
getSeconds() 返回秒数(0-59)
getMilliseconds() 返回毫秒(0-999)

这个对象的方法太多了,就不一一列举了,参考菜鸟教程

  • Array
    和 String 对象有些是类似的
方法 描述
concat() 连接两个或更多的数组,并返回结果。
copyWithin() 从数组的指定位置拷贝元素到数组的另一个指定位置中。
entries() 返回数组的可迭代对象。
every() 检测数值元素的每个元素是否都符合条件。
fill() 使用一个固定值来填充数组。
filter() 检测数值元素,并返回符合条件所有元素的数组。
find() 返回符合传入测试(函数)条件的数组元素。
findIndex() 返回符合传入测试(函数)条件的数组元素索引。
forEach() 数组每个元素都执行一次回调函数。
from() 通过给定的对象中创建一个数组。
includes() 判断一个数组是否包含一个指定的值。
indexOf() 搜索数组中的元素,并返回它所在的位置。
isArray() 判断对象是否为数组。
join() 把数组的所有元素放入一个字符串。
keys() 返回数组的可迭代对象,包含原始数组的键(key)。
lastIndexOf() 搜索数组中的元素,并返回它最后出现的位置。
map() 通过指定函数处理数组的每个元素,并返回处理后的数组。
pop() 删除数组的最后一个元素并返回删除的元素。
push() 向数组的末尾添加一个或更多元素,并返回新的长度。
reduce() 将数组元素计算为一个值(从左到右)。
reduceRight() 将数组元素计算为一个值(从右到左)。
reverse() 反转数组的元素顺序。
shift() 删除并返回数组的第一个元素。
slice() 选取数组的的一部分,并返回一个新数组。
some() 检测数组元素中是否有元素符合指定条件。
sort() 对数组的元素进行排序。
splice() 从数组中添加或删除元素。
toString() 把数组转换为字符串,并返回结果。
unshift() 向数组的开头添加一个或更多元素,并返回新的长度。
valueOf() 返回数组对象的原始值。
  • RegExp 对象

    1. .test()

    test() 方法是一个正则表达式方法。
    test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
    例如: /e/.test("regex"); // true

    1. .exec()

    exec() 方法是一个正则表达式方法。
    exec() 方法用于检索字符串中的正则表达式的匹配。
    该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
    例如:/e/g.exec("The best things in life are free!"); // "e", index: 2

那这个和字符串的方法 .match() 有什么区别呢?
我们可以注意到,exec 方法的例子,明明用了全局匹配,却只匹配到了一个 "e",也就是第一个匹配到的那个。
那我们来看几种情况:

var str = "hellobell";
str.match(/ell/);
// ["ell", index: 1, input: "hellobell", groups: undefined]

str.match(/ell/g);
// (2) ["ell", "ell"]

/ell/.exec(str)
// ["ell", index: 1, input: "hellobell", groups: undefined]

/ell/g.exec(str)
// ["ell", index: 1, input: "hellobell", groups: undefined]

在没加全局匹配的时候,大家都是一样的,但加上全局的时候,只有 .match() 是有效的。

var p = /h(ell)/;

str.match(p);
// (2) ["hell", "ell", index: 0, input: "hellobell", groups: undefined]0: "hell"1: "ell"groups: undefined

p.exec(str)
// (2) ["hell", "ell", index: 0, input: "hellobell", groups: undefined]

var p = /h(ell)/g;

str.match(p);
// ["hell"]

p.exec(str)
// (2) ["hell", "ell", index: 0, input: "hellobell", groups: undefined]

这个时候是反过来的。

所以总结:

1) 当无g时,match的返回结果和exec是相同的,有无分组不受影响,当有g时,其将返回包含所有匹配项的数组。
2) 当有分组时,exec返回数组的第一个元素为匹配的完整串.后续元素为括号里捕获的字符串,当无分组时,只返回第一个匹配,g有没有都无影响。

这次先总结这么多,有不对的地方欢迎指出~

参考:JavaScript对象基础讲解

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容

  • JavaScript对象就是一组属性和方法(函数)的集合。 创建对象字面量表示法:一个对象也需要用一个变量来存储,...
    竹鼠不要中暑阅读 834评论 0 0
  • 对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法) 创建一个对象通常先...
    咖A喱阅读 185评论 0 0
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,092评论 0 21
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,360评论 0 4
  •   引用类型的值(对象)是引用类型的一个实例。   在 ECMAscript 中,引用类型是一种数据结构,用于将数...
    霜天晓阅读 1,031评论 0 1