给原始数据类型加属性和方法为什么不会报错?闭包类——阿里面试题

前言

我们知道在JS有两大数据类型,一种是原始数据类型,一种是引用数据类型。引用数据类型比如对象,它是自带方法的,我们也可以给它加入属性和方法。但是原始数据类型没有属性和方法,那我们给原始数据类型加入属性和方法时,为什么不会报错呢?

我们先看一个例子:

js 复制代码
var obj = {}
obj.a = 123
console.log(obj.a);
console.log(obj.b);

我们可以通过对象.属性 = 某某值的方法来创建一个键值对,那么当我们访问一个对象中没有的属性时,又会输出什么呢?

当我们访问对象中不存在的属性,并不会报错,而是输出undefined。

这个问题我们先留在这,我相信再我们讲完之后你自己就能解决了。

注:接下来会用到构造函数,不太了解的小伙伴们可以看看我的上篇文章:构造函数

包装类

原始值是不能拥有属性和方法的,属性和方法是对象才独有的

原始数据类型可以通过包装对象来拓展功能

js 复制代码
var num = 123
num.abc = 'hello'
console.log(num.abc);

当小伙伴们看到这道题时,一定会很懵吧。什么?还能给原始数据类型加上属性?那么输出一定会报错吧!我们来看看输出结果

输出为undefined,而不是报错。这是为什么呢?

其实,当我们给原始数据类型添加属性时,引擎就会进行以下的操作。当我们var num = 123时,其实就相当于var num = new Number(123) ,上篇文章中我们讲到,使用了new返回的一定是一个对象 ,所以num短暂的成为了一个对象,所以可以暂时给num加上属性和方法 ,所以num.abc = 'hello',但是之后引擎反应过来了,原始数据类型是不能添加属性和方法的,所以又会detele num.abc .那小伙伴们,那为什么最后还会输出undefined,被删掉了不应该是报错吗?确实是删掉了,但当执行到console.log(num.abc)时,引擎又会执行一个操作,那就是new Number(123).abc ,而这就叫做隐式包装类,但是并没有赋值,所以我们最后输出为undefined

我们用代码来解释一下:

js 复制代码
var num = 123
// var num = new Number(123)
num.abc = 'hello'
// num.abc = 'hello'
// delete num.abc

// new Number(123).abc
console.log(num.abc);   // 输出undefined

我们再来看一道题:

js 复制代码
var num = 4
num.len = 3
console.log(num.len);

这里也是输出为undefined,小伙伴们可以思考一下

js 复制代码
var num = 4
num.len = 3

// var num = new Number(4)
// num.len = 3
// delete num.len

// new Number(4).len   //隐式包装类
 console.log(num.len);  // 输出undefined
 

接下来我们来讲一道考点:

js 复制代码
var arr = [1, 2, 3, 4, 5]
arr.length = 2
console.log(arr);

var str = 'abcd'
console.log(str.length);

我们先来看看输出结果:

数组我相信小伙伴们已经很熟悉了,数组是引用数据类型,是具有属性和方法的,所以可以用arr.length修改数组的长度。如果做过字符串有关题目的小伙伴们,一定会知道字符串是有str.length这个属性的,接下来我们拿代码分析一下:

js 复制代码
var arr = [1, 2, 3, 4, 5]
arr.length = 2
console.log(arr);

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

当执行到console.log(str.length)时,引擎还是会生成一个new String('abcd').length,但这里为什么会输出一个值呢,因为字符串.length这个方法本身就存在,它是在字符串创造时就已经打造出来的,所以这里会输出字符串的长度。

阿里面试题

js 复制代码
var str = 'abc'
str += 1    //字符串加任何东西都是字符串
var test = typeof (str) //'string'
if (test.length == 6) {
    test.sign = 'typeof的返回结果可能为String'
}
console.log(test.sign);

问:这里会输出什么?

js 复制代码
var str = 'abc'
str += 1    //字符串加任何东西都是字符串
var test = typeof (str) //'string'
if (test.length == 6) {  // new String(test).length
    test.sign = 'typeof的返回结果可能为String'
    //new String(test).sign = 'typeof的返回结果可能为String'
    //delete
}
// new String(test).sign
console.log(test.sign);

你看,你又拿下了一道阿里面试题,是不是也没那么难呢?

总结

原始值是不能拥有属性和方法的,属性和方法是对象才独有的

原始数据类型可以通过包装对象来拓展功能

今天的内容就到这啦,如果你觉得小编写的还不错的话,或者对你有所启发,请给小编一个辛苦的赞吧

相关推荐
mfxcyh1 分钟前
Vue3+Ant Design Vue 实现手动异步文件上传(含大小校验、弹窗上传)
前端·javascript·vue.js
wordbaby2 分钟前
Web端热敏标签打印完整解决方案(QZ Tray + 译维A42)
前端
swipe6 分钟前
03|Axios 请求进了后端之后:Controller、Request、Response 是怎么接住它的?
前端·后端·全栈
meilindehuzi_a12 分钟前
Vue3进阶基础:指令修饰符、v-model表单绑定、动态样式、计算属性与侦听器实战
前端·javascript·vue.js
csdn2015_18 分钟前
vue 前端运行命令
前端·javascript·vue.js
swipe18 分钟前
02|从 `pnpm dev` 到 Spring Boot 启动:后端服务到底怎么跑起来?
前端·后端·全栈
swipe31 分钟前
01|前端人第一次打开 Spring Boot 项目,应该先看哪里?
前端·后端·全栈
Cobyte37 分钟前
根据浏览器解析 HTML 的规范实现 HTML 解析器
前端·javascript·vue.js
风栖柳白杨1 小时前
【面试】职位要求_准备
面试·职场和发展
阿懂在掘金1 小时前
做命令式弹窗工具应该考虑什么——我为什么把 vue-layerx 设计成这样
前端·前端框架·函数式编程