JavaScript对象

简介: JavaScript对象

1. 对象的基本使用

  • 对象只是一种特殊的数据。对象拥有属性和方法;
  • 对象内部属性由key: value的键值对组成, 其中key是字符串类型(大部分情况下引号会被省略,另外es6后可以用Symbol类型), vaule可以是任意类型, 包括基本数据类型, 对象, 函数等;
  • 点符号要求key是有效的变量标识符,不能包含空格, 不能以数字开头, 也不能包含某些特殊字符, 这个时候我们可以使用[]
  // 1. 对象的基本结构
  var person = {
    name: "zgc",
    age: 18,
    eat: function () {
      console.log("eating");
    },
    // 这种情况下需要引号
    "my friend": "wf",
  };
  console.log(person);
  // 2. 对象的常见操作
  // (1) 对象的创建方式:
  // 方式1:字面量创建
  var obj1 = {
    name: "zgc",
    age: 10,
    running: function () {
      console.log("running");
    },
  };
  // 方式2: new Object
  var obj2 = new Object();
  // 方式3: new 其他类
  function Person() {}
  var obj3 = new Person();
  // (2) 对象的增删改查
  // 查询对象属性
  console.log(obj1.age, obj1.name); // 10 'zgc'
  obj1.running(); // running
  // 修改对象属性
  person.age = 40;
  console.log(person.age); // 40
  // 添加对象属性
  obj2.name = "zgc";
  obj2.study = function () {
    console.log("study");
  };
  console.log(obj2);
  obj2.study(); // study
  // 删除对象属性
  // delete操作符
  delete person.name;
  console.log(person);
  // 3. 方括号的使用
  // 点符号要求key是有效的变量标识符,不能包含空格, 不能以数字开头, 也不能包含某些特殊字符, 这个时候我们可以使用[]
  var message = "Hello World";
  var info = {
    name: "zgc",
    age: 29,
    "my friend": "wf",
    "paly games": function () {
      console.log("games");
    },
    [message]: "你好, 世界",
  };
  console.log(info.name === info["name"]); //true
  console.log(info["my friend"]); // wf
  info["paly games"](); // games
  var play = "paly games";
  info[play](); // games
  console.log(info[message]); // 你好, 世界

2. 对象的遍历

  var info = {
    name: "zgc",
    age: 18,
    height: 1.88,
  };
  // Object.keys(): 拿到对象的所有属性名, 返回一个由属性名组成的数组
  // 1. for
  const arr = Object.keys(info);
  console.log(arr); // ['name', 'age', 'height']
  for (var i = 0; i < arr.length; i++) {
    var value = info[arr[i]];
    console.log(value); // zgc 18 1.88
  }
  console.log("---------------------------");
  // 2. for in
  for (var key in info) {
    console.log(key);
    console.log(info[key]);
  }
  // name;
  // zgc;
  // age;
  // 18;
  // height;
  // 1.88;
  // 3. for of: 默认情况下是不能遍历对象的
  for (var key of info) {
    //  报错: info is not iterable
  }

3. 内存

  • 程序是需要加载到内存中来执行的, 我们可以将内存划分为两个区域: 栈内存和堆内存;
  • 原始类型占据的空间是在 栈内存(stack) 中分配的
  • 对象类型占据的空间是在 堆内存(heap) 中分配的
  • 值(基础)类型:直接存储在栈中的数据,其操作方式为传值;
  • 引用类型:存储在栈中的是该对象的引用,真实的数据存放在堆内存里,其操作方式为传址;
  // 1.
  var obj = {
    name: "zgc",
    age: 18,
  };
  var info = obj;
  obj.age = 20;
  console.log(obj.age, info.age); // 20 20
  var msg = "Hello";
  var detail = msg;
  console.log(msg, detail); // Hello Hello
  msg = "World";
  console.log(msg, detail); // World Hello
  var obj2 = {};
  var obj3 = {};
  // 2.
  console.log(info === obj); // true;
  console.log(obj2 === obj3); // false;
  var msg1 = "Hello";
  console.log(msg === msg1); //true
  var user = {
    name: "zgc",
    friend: {
      name: "wf",
    },
  };
  var friend = user.friend;
  friend.name = "wlc";
  console.log(user.friend.name); // wlc;
  // 3.
  function foo(a) {
    a = 200;
  }
  var baz = 100;
  foo(baz);
  console.log(baz); // 100
  // 4.
  function foo1(a) {
    a.age = 18;
    // 创建了一个新对象, 没有对传入对象进行修改
    a = {
      name: "wf",
    };
  }
  var baz = {
    name: "zgc",
  };
  foo1(baz);
  console.log(baz); // {name: 'zgc', age =18}

4. 工厂函数

对象都是通过工厂造就的全新的对象。

优势:

  • 工厂函数可以解决创建多个类似功能对象的问题。

缺点:

  • 工厂模式无法解决对象的识别问题: 不能明确表示对象是什么类型的, 都是Object类型
  function createPerson(name, age, height) {
    let o = new Object();
    o.name = name;
    o.age = age;
    o.height = height;
    o.sayName = function () {
      console.log(this.name);
    };
    return o;
  }
  function createStudent() {
    let o = {};
    return o;
  }
  let person1 = createPerson("zgc", 23, "1.88");
  let person2 = createPerson("wf", 25, "1,89");
  let student = createStudent();
  console.log(person1, person2, student); 
  // 在打印对象时, 都是Object类型的对象: Object Object Object

5. 构造函数

工厂函数, JS已经默认提供了一种更加符合JavaScript思维方式(面向对象的思维方式)的创建对象的规则

  • 构造函数也称之为构造器, 通常是我们在创建对象时会调用的函数
  • 构造函数的函数名通常使用大写字母开头

如果一个函数被new操作符调用 :


  1. 首先在堆内存中创建了一个新的空对象
  2. 设置原型,将对象的原型设置为构造函数的prototype属性。
  3. 让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象(注: 不写rteturn默认返回undefined, 是值类型)。如果是引用类型,就返回这个引用类型的对象。
  function Person(name, age, height) {
    this.name = name;
    this.age = age;
    this.height = height;
    this.sayName = function () {
      console.log(this.name);
    };
  }
  function Student() {}
  var person1 = new Person("zgc", 23, "1.88");
  var person2 = new Person("wf", 25, "1,89");
  var student = new Student();
  console.log("构造函数", person1, person2, student); 
  // 在打印对象时, 可以看到对象的具体类型: Person Person Student

6. 对象额外补充

  // 1. 全局对象: 浏览器中存在一个全局对象window
  console.log(window);
  // 作用1: 查找变量时, 最终会找到window身上, 如果window也不存在该变量就会报错
  // 作用2: 将一些浏览器全局提供给我们的变量/方法/对象放在window上面, 方便我们使用
  // 作用3: 使用var定义的全局变量会被添加到window上面
  var message = "zgc";
  console.log(window.message); // zgc
  function foo() {
    // abc(); // abc is not defined
    alert("zgc"); // alert方法在window上, 所以能够使用
    console.log(window.console === console); // true
  }
  // foo();
  // 2. 函数也是一个对象
  var foo = function () {}; // 存储在堆内存中
  function bar() {} // 存储在堆内存中
  var baz = foo; // 存储在堆内存中, baz和foo都是同一个内存地址, 指向同一块存储数据

7. 原始类型的包装类型

JavaScript的原始类型并非对象类型, 所以从理论上来讲, 它们是没有办法获取属性和调用方法的; 但是在实际上,每当读取一个基本类型的时候,js内部会自动创建一个基本包装类型对象,可以让我们调用一些方法来操作; 该包装类型只存在于一行代码的执行瞬间,然后立即销毁

JavaScript 你不知道的基本包装类型 - percy507的编程之路 - SegmentFault 思否

  • js中为了便于基本类型操作,提供了5个特殊的引用类型:Boolean、Number、String、Symbol、BigInt它们具有基本类型特殊行为。
  • 即除了 null 和 undefined,所有的原始值都有等价的、由对象包装原始值的形式表达,null 和 undefined没有任何方法. 也没有对应的对象包装类型
  • 引用类型与基本包装类型的主要区别就是对象的生存期


使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前,会一直保存在堆内存中。而后台自动创建的基本包装类型的对象,则只存在一行代码的执行瞬间,然后立即被销毁。这意味着我们不能为基本类型的值添加属性和方法。

  // JavaScript的原始类型并非对象类型, 所以从理论上来讲, 它们是没有办法获取属性和调用方法的
  // 但是, 在开发中我们经常会看到类似操作:
  var message = "Hello World";
  console.log(message.length); // 11
  var num = 12.34567;
  console.log(num.toFixed(2)); // 12.35
  // 为什么会出现这种现象呢?
  // 原始类型是简单的值, 默认不能调用属性和方法
  // 这是因为JS为了使其获取属性和调用方法, 对其封装了对应的包装类型
  // 案例:
  var str = "hello zgc";
  var str1 = str.substring(2);
  // 等价于:
  var str = new String("hello zgc"); // 创建String类型的实例, 浏览器内部默认执行
  var str1 = str.substring(2); //在实例上调用指定的属性或方法
  str1 = null; // 销毁这个实例
  // 不能为基本类型的值添加属性和方法
  var str = 'zgc'
  str.age = 23
  console.log(str.age) // undefined

8. 包装类型-Number类型

  // Number实例方法:
  var num = 3.1415926; // 等价于new Number(3.1415926) -> 包装类型
  // 1. toString(base), 将数字转化为字符串, 并且按照base进制进行转化
  // base的范围是 2 - 36, 默认情况下是10
  var str = num.toString();
  console.log("str", str, typeof str, "num", num, typeof num);
  // str 3.1415926 string num 3.1415926 number
  console.log(num.toString(2)); // 转化为2进制的字符串类型
  console.log(num.toString(8)); // 转化为8进制的字符串类型
  console.log(num.toString(16)); // 转化为16进制的字符串类型
  // 2. toFixed(digits) 格式化一个数字, 保留digits小数位, 会进行四舍五入
  // digits的范围是 0 - 20(包含) 之间
  var pi = num.toFixed(3); // 返回值是string类型
  console.log(pi); // 3.142
  // Number类方法:
  var msg = "123.321";
  console.log(Number(msg)); // 123.321
  // 1. Number.parseInt(string, radix), 将字符串解析成整数, 也有对应的全局方法parseInt
  // radix(可选 ):表示要解析的数字的基数。该值介于 2 ~ 36 之间。
  // 值不会进行四舍五入
  console.log(Number.parseInt(msg)); // 123
  // 在window上的方法
  console.log(parseInt(msg)); // 123
  // 2.  Number.parseFloat(), 将字符串解析成浮点数, 也有对应的全局方法parseFloat
  console.log(Number.parseFloat(msg)); // 123.321
  console.log(parseFloat(msg)); // 123.321
  console.log(window.parseInt === Number.parseInt); //true

9. 内置对象-Math

  • Math是一个内置对象(不是构造函数), 它拥有一些数学常数属性和数学函数方法
  // Math是一个内置对象(不是构造函数), 它拥有一些数学常数属性和数学函数方法
  console.log(typeof Number); // function
  console.log(typeof Math); // object
  // 1. pi的值
  console.log(Math.PI); // 3.141592653589793
  // 2. 向上舍入取整
  console.log(Math.ceil(3.55)); //  4
  // 3. 向下舍入取整
  console.log(Math.floor(3.55)); //  3
  // 4. 四舍五入取整
  console.log(Math.round(3.55)); //  4
  // 5. 生成 [0, 1)的随机数
  console.log(Math.random());
  // 6. Math.pow(x, y) x的y次幂
  console.log(Math.pow(2, 3)); //  8
  // 7. 取绝对值
  console.log(Math.abs(-32)); // 32
  // 案例1: 生成 [5, 50) 的随机整数
  var num = Math.floor(Math.random() * 45) + 5;
  console.log(num);

10. 包装类型-String类型

基本使用

  var msg = "Hello World";
  // 1. 获取字符串长度
  console.log(msg.length); // 11
  // 2. 返回在指定位置的字符
  console.log(msg[4]); // o
  console.log(msg.charAt(0)); // H
  // 这两种方法的区别是, 访问不到字符位置时charAt返回一个空字符串, 索引方式返回undefined
  // 3. 字符串遍历
  // for普通遍历
  for (var i = 0; i < msg.length; i++) {
    console.log(msg[i]);
  }
  // for...of
  // 对象默认不支持for...of
  // String对象内部是将字符串变成了一个可迭代对象, 所以能够使用for...of
  for (var char of msg) {
    console.log(char);
  }

修改字符串

  • 字符串在定义后是不可以修改的, 所以下面操作是没有意义的
  • 但是可以给变量重新赋值新的字符串
  msg[2] = "q";
  console.log(msg); // my name is zgc
  // msg中所有字符大写 toUpperCase
  // msg中所有字符小写 toLowerCase
  var msg1 = msg.toUpperCase(); // 根据原来字符串生成新的字符串, 原字符串没有改变
  console.log(msg1, msg); // MY NAME IS ZGC my name is zgc
  // 替换字符串
  var msg2 = msg.replace("zgc", "wf"); // 根据原来字符串生成新的字符串, 原字符串没有改变
  console.log(msg2, msg); // my name is wf my name is zgc

查找字符串

  • 在一个字符串中查找或者获取另一个字符串
  // (1) indexOf(): 对大小写敏感!
  // 搜索到, 返回字符串所在的索引位置, 没有搜索到返回-1
  var str = "Hello world!";
  console.log(str.indexOf("Hello")); // 0
  console.log(str.indexOf("World")); // -1
  console.log(str.indexOf("world")); // 6
  // (2) includes(): 返回布尔值,表示是否找到了参数字符串
  let s = "Hello world!";
  console.log(s.includes("Hello")); // true
  // 支持第二个参数,表示开始搜索的位置
  console.log(s.includes("Hello", 6)); // false
  console.log(s.includes("world", 6)); // true

获取子字符串

  • slice: 提取字符串的片断,并在新的字符串中返回被提取的部分, 原字符串不变
  • slice(start,end); 取值范围: [start,end), 且允许负值
  • start :要抽取的片断的起始下标。如果是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推。
  • end:紧接着要抽取的片段的结尾的下标。若未指定此参数,则要提取的子串包括 start 到原字符串结尾的字符串。如果该参数是负数,那么它规定的是从字符串的尾部开始算起的位置。
  var str = "abc def ghk";
  var newStr1 = str.slice(6);
  console.log(str, newStr1); //abc def ghk f ghk
  var newStr2 = str.slice(2, 5);
  console.log(newStr2); // c d
  var newStr3 = str.slice(4, -1);
  console.log(newStr3); // def gh

其他常用方法补充

  // 6. 字符串拼接
  // 方式1: concat()
  var a = "abc";
  var b = "def";
  var c = "gh";
  var d = a.concat(b).concat(c);
  var e = a.concat(b, c, "zgc");
  console.log(d); //abcdefgh
  console.log(e); //abcdefghzgc
  // 方式2: +
  var f = a + b + c;
  console.log(f); // abcdefgh
  // 7. 删除首尾空格: str.trim()
  console.log("   zgc    ".trim());
  // 8. 字符串切割 split(): 把字符串分割为字符串数组
  // 原字符串不变
  var message = "abc-def-ghi-jkl";
  var str = "abc def ghi jkl";
  console.log(str.split(" ")); //["abc", "def", "ghi", "jkl"]
  console.log(message.split("-")); //["abc", "def", "ghi", "jkl"]
  console.log(str.split("")); //["a", "b", "c", " ", "d", "e", "f", " ", "g", "h", "i", " ", "j", "k", "l"]
  console.log(str.split(" ", 3)); //["abc", "def", "ghi"]
相关文章
|
5天前
|
JSON JavaScript 前端开发
JavaScript实现字符串转json对象的方法
JavaScript实现字符串转json对象的方法
|
8天前
|
JavaScript 前端开发
js之DOM 文档对象模型
js之DOM 文档对象模型
8 1
js之DOM 文档对象模型
|
1天前
|
JSON JavaScript 前端开发
如何检查 JavaScript 对象是否为空
【8月更文挑战第18天】
14 0
如何检查 JavaScript 对象是否为空
|
4天前
|
JavaScript 前端开发
JavaScript BOM 的概念(浏览器对象模型)
JavaScript BOM 的概念(浏览器对象模型)
12 1
|
5天前
|
JavaScript 前端开发
JavaScript基础&实战(5)js中的数组、forEach遍历、Date对象、Math、String对象
这篇文章介绍了JavaScript中的数组、Date对象、Math对象以及包装类(String、Number、Boolean),并详细讲解了数组的创建、方法(如forEach、push、pop、unshift、slice、splice)和遍历操作,以及工厂方法创建对象和原型对象的概念。
JavaScript基础&实战(5)js中的数组、forEach遍历、Date对象、Math、String对象
|
5天前
|
JavaScript 前端开发
JavaScript基础&实战(4)js中的对象、函数、全局作用域和局部作用域
这篇文章介绍了JavaScript中对象的基本概念和操作,包括对象属性和方法的使用、对象字面量的创建、函数的定义和作用域的概念,以及全局作用域和局部作用域的区别和特性。
JavaScript基础&实战(4)js中的对象、函数、全局作用域和局部作用域
|
11天前
|
JavaScript 数据处理
如何使用 Vue.js 将数据对象的值放入另一个数据对象中?
如何使用 Vue.js 将数据对象的值放入另一个数据对象中?
|
17天前
|
JavaScript 前端开发 Java
什么是JavaScript原型对象
【8月更文挑战第2天】什么是JavaScript原型对象
39 9
|
5天前
|
JavaScript 前端开发
js之DOM 文档对象模型
js之DOM 文档对象模型
|
5天前
|
JavaScript 前端开发
JS遍历数组和对象的方法有哪些
JS遍历数组和对象的方法有哪些

热门文章

最新文章