likes
comments
collection
share

Javascript中的对象与包装类,解决百度面试送分题

作者站长头像
站长
· 阅读数 31

前言

前端学习中有句话:“Javascript万物皆对象”,这意味着在JavaScript中,几乎所有的东西都是对象,包括基本数据类型(如字符串、数字和布尔值),甚至其中的函数也是对象,它们可以有属性和方法,并且可以作为参数传递给其他函数。对象在js中起着至关重要的作用。接下来通过面试题解析了解对象和包装类。

正文

var str = 'asdfg' 
str += 1  
var test = typeof(str) 
if (test.length == 6) {
    test.sign = 'typeof的返回值可能为String'
}
console.log(test.sign)

快速思考一下这送分题的答案,答案是undefined 至于为什么?让我们细细研究

介绍下对象

基本的JavaScript对象类型:

  1. 原始类型包装对象:字符串(String)、数字(Number)、布尔值(Boolean)等,它们都有对应的构造函数,可以将原始类型转换为对象。
  2. 引用类型:对象(Object)、数组(Array)、函数(Function)、日期(Date)等,它们是由构造函数创建的复杂数据结构。

更加细节一点就还有特殊对象以及宿主对象

对象是 JavaScript的基础。在 JavaScript 中一共有六种主要类型(术语是“语言类型”):

  • string
  • boolean
  • number
  • null
  • undefined
  • object

注意,简单基本类型(string、boolean、 number、null 和 undefined)本身并不是对象。

其实JavaScript中有许多特殊的对象子类型,我们可以称之为复杂基本类型

函数就是对象的一个子类型(从技术角度来说就是“可调用的对象”)。JavaScript 中的函数本质上和普通的对象一样(只是可以调用),所以可以像操作其他对象一样操作函数(比如当作另一个函数的参数)。

数组也是对象的一种类型,具备一些额外的行为。只不过数组中内容的组织方式比一般的对象要稍微复杂一些。

因此JavaScript中“万物皆是对象”,这句话显然是错误的。

对象的创建

对象可以通过两种形式定义:声明(文字)形式和构造形式

1、声明(文字)形式创建对象字面量

var obj = {
    key:value
} 

2、创建对象实例,对象类型的构造函数

var obj2 = new Object()  

构造函数可以自定义

function Car(color){
    this.name = 'bba'
    this.hight = 1400
    this.long = 3000
    this.color = color
    this.weight = 1000
}

new关键字

构造函数就是一种特殊的函数,只有在new关键字调用后才会创建一个新的对象,并将这个对象与构造函数关联起来。

new 的过程发生了什么

  • 先创建一个object空对象{}
  • 将构造函数constructor,以new的方式运行
  • this 指向实例,运行的过程就是实例逐渐添加属性的过程
  • 最后默认返回对象

包装类

在 JavaScript 中,为了便于操作基本类型值,ECMAScript 提供了一些特殊的引用类型,也称为基本包装类型,包括 Boolean、Number 和 String 等。

基本包装类型的主要作用是在后台自动创建对应的对象,以便对基本类型值进行操作。每当读取一个基本类型值时,JavaScript 引擎会自动创建一个对应的基本包装类型对象,从而可以调用一些方法来操作这些数据。这种转换是临时的,调用完成后,这些临时创建是包装对象会被立即销毁。

于是可以解释以下代码的运行

var num = 4  
//相当于new Number(4)
num.len=5  
// 相当于new Number(4).len=5
// 接着引擎 delete num.len 就算增加了属性也会立即删除
console.log(num.len);//输出的是undefined 而不是报错

但这时便会思考,为什么是undefined而不是直接输出5呢?

这是因为:原始值是不允许拥有属性和方法,只有对象才能拥有属性和方法,这种隐式的过程就称之为包装类

那我们再往下看

var str = 'sadf' //相当于new String('sadf')
console.log(str.length); 
//

那这里的结果是4为什么不是undefined?不是说了原始值是不允许拥有属性和方法吗?

解释为:字符串是原始值,而字符串对象没有length属性,但它经历了new过程,相当于new String('sadf') String这种基本包装类型它具有一些属性和方法,如 length 属性表示字符串的长度

在 JavaScript 中,Boolean、Number 和 String 具有与各自基本类型相应的特殊行为,具体如下:

  • Boolean 类型:Boolean 类型是布尔值对应的引用类型。它重写了 valueOf() 方法,返回基本类型值 true 或 false;重写了 toString() 方法,返回字符串 "true" 和 "false"。

  • Number 类型:Number 类型是数字对应的引用类型。它提供了一些方法,如 toFixed() 方法用于保留指定小数位数,toExponential() 方法用于以指数形式表示数字。

  • String 类型:String 类型是字符串对应的引用类型。它具有一些属性和方法,如 length 属性表示字符串的长度,charAt()、charCodeAt() 方法用于获取指定位置的字符,concat() 方法用于拼接字符串,substr()、substring() 和 slice() 方法用于复制字符串的一部分。

这些特殊行为使得基本类型的值能够像对象一样进行操作,提供了更方便的编程接口。

再来看看这两个例子

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.length = 5;
console.log(arr.length);

var str = 'asdfg' //new String('asdfg')
str.length = 2; //new String('asdfg').length = 2;
console.log(str.length);

为什么这两个输出的结果都为5

字符串是不可变的,意味着你不能改变字符串中的单个字符或其长度。当你尝试设置str.length = 2,JavaScript引擎会先增加这个属性,但引擎会立马反应过来并删除这个属性,因为字符串对象不允许有可写属性。由于字符串是原始值,当你访问str.length时,实际上是在访问字符串的原始长度,而不是对象的属性。

最后回到我们开头的面试题

var str = 'asdfg' 
str += 1  
var test = typeof(str) 
if (test.length == 6) {
    test.sign = 'typeof的返回值可能为String'
}
console.log(test.sign)
  • 前三行的结果为将test判断为'asdfg1被赋予了字符串"string"
  • 因此,学习了今天的知识便可以直接秒杀了,因为字符串字面量"string"没有.sign属性。即使在前面的if语句中尝试设置它,也是无效的,因为字符串字面量是不可变的,也不支持动态添加属性。
  • 当执行console.log(test.sign)时,结果是undefined

结语

JavaScript 中的包装类(Wrapper Classes)指的是能够将原始数据类型(如字符串、数字、布尔值)包装成对象的构造函数。原始数据类型本身不是对象,但 JavaScript 提供了三个包装类来允许原始数据类型表现得像对象:

  1. String:将字符串原始值包装成字符串对象。
  2. Number:将数字原始值包装成数字对象。
  3. Boolean:将布尔值原始值包装成布尔对象。

例如:

var str = "Hello"; // 原始字符串
var strObj = new String(str); // 使用String包装类创建字符串对象

var num = 42; // 原始数字
var numObj = new Number(num); // 使用Number包装类创建数字对象

var bool = true; // 原始布尔值
var boolObj = new Boolean(bool); // 使用Boolean包装类创建布尔对象

包装对象提供了一些有用的方法和属性,例如:

  • String 对象有 length 属性和 charAt()substring() 等方法。
  • Number 对象有 toFixed()toExponential() 等方法。
  • Boolean 对象通常没有太多额外的方法,因为布尔值只有两个可能的值。

通常,我们可以通过调用原始数据类型的构造函数而不使用 new 关键字来获得类似包装对象的行为,例如:

var strObj = String("Hello"); // 等同于 new String("Hello")
var numObj = Number(42); // 等同于 new Number(42)
var boolObj = Boolean(true); // 等同于 new Boolean(true)

这种方式不会创建一个实际的对象实例,而是返回一个原始类型的值,但提供了一些类似于包装对象的功能。

转载自:https://juejin.cn/post/7376532114105385011
评论
请登录