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

前言

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

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

总结

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

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

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

相关推荐
GoldKey1 小时前
gcc 源码阅读---语法树
linux·前端·windows
Xf3n1an2 小时前
html语法
前端·html
张拭心2 小时前
亚马逊 AI IDE Kiro “狙击”Cursor?实测心得
前端·ai编程
岁忧2 小时前
(nice!!!)(LeetCode 面试经典 150 题 ) 30. 串联所有单词的子串 (哈希表+字符串+滑动窗口)
java·c++·leetcode·面试·go·散列表
漠月瑾-西安2 小时前
如何在 React + TypeScript 中实现 JSON 格式化功能
javascript·jst实现json格式化
烛阴2 小时前
为什么你的Python项目总是混乱?层级包构建全解析
前端·python
止观止3 小时前
React响应式组件范式:从类组件到Hooks
javascript·react.js·ecmascript
@大迁世界3 小时前
React 及其生态新闻 — 2025年6月
前端·javascript·react.js·前端框架·ecmascript
LJianK13 小时前
Java和JavaScript的&&和||
java·javascript·python
红尘散仙4 小时前
Rust 终端 UI 开发新玩法:用 Ratatui Kit 轻松打造高颜值 CLI
前端·后端·rust