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

前言

我们知道在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);

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

总结

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

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

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

相关推荐
超哥--2 小时前
B站视频内容智能分析系统(九):React 前端与管理面板
前端·react.js·前端框架
Cutecat_5 小时前
视频字幕处理工具横向:提取模式 vs 编辑模式,该如何选择
android·前端·ios·语音识别
dsyyyyy11015 小时前
JavaScript变量
开发语言·javascript·ecmascript
qq_422152575 小时前
PDF 加水印工具怎么选?2026 年文档版权保护方案对比
前端·pdf·github
kyriewen5 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
brucelee1866 小时前
OpenClaw 浏览器控制(Chrome MCP)完整教程
前端·chrome
ct9786 小时前
React 状态管理方案深度对比
开发语言·前端·react
胡志辉的博客7 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖7 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty7 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js