百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

面试官想要的 JS 基本类型

toyiye 2024-06-21 11:58 14 浏览 0 评论

面试的时候我们经常会被问答js的数据类型。大部分情况我们会这样回答包括:

  1. 基本类型(值类型或者原始类型): Number、Boolean、String、NULL、Undefined以及ES6的Symbol;
  2. 引用类型:Object、Array、Function、Date等。

作者曾经也是这样回答的,并且一直觉得没有什么问题。那么面试官问你 JS 数据类型时,他想知道什么呢?接着往下看

1. 在内存中的位置不同

  • 基本类型: 占用空间固定,保存在栈中
  • 引用类型:占用空间不固定,保存在堆中

栈(stack)为自动分配的内存空间,它由系统自动释放;使用一级缓存,被调用时通常处于存储空间中,调用后被立即释放。

堆(heap)则是动态分配的内存,大小不定也不会自动释放。使用二级缓存,生命周期与虚拟机的GC算法有关

当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的;栈中存储的是基础变量以及一些对象的引用变量,基础变量的值是存储在栈中,而引用变量存储在栈中的是指向堆中的数组或者对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。

当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

2. 赋值、浅拷贝、深拷贝

  • 对于基本类型值,赋值、浅拷贝、深拷贝时都是复制基本类型的值给新的变量,之后二个变量之间操作不在相互影响。
  • 对于引用类型值,分以下三个方面:
  • 赋值后二个变量指向同一个地址,一个变量改变时,另一个也同样改变;
  • 浅拷贝后得到一个新的变量,这个与之前的已经不是指向同一个变量,改变时不会使原数据中的基本类型一同改变,但会改变会原数据中的引用类型数据
  • 深拷贝后得到的是一个新的变量,她的改变不会影响元数据

 var obj1 = {
 'name' : 'zhangsan',
 'age' : '18',
 'language' : [1,[2,3],[4,5]],
 };
 var obj2 = obj1;
 var obj3 = shallowCopy(obj1);
 function shallowCopy(src) {
 var dst = {};
 for (var prop in src) {
 if (src.hasOwnProperty(prop)) {
 dst[prop] = src[prop];
 }
 }
 return dst;
 }
 obj2.name = "lisi";
 obj3.age = "20";
 obj2.language[1] = ["二","三"];
 obj3.language[2] = ["四","五"];
 console.log(obj1); 
 //obj1 = {
 // 'name' : 'lisi',
 // 'age' : '18',
 // 'language' : [1,["二","三"],["四","五"]],
 //};
 console.log(obj2);
 //obj2 = {
 // 'name' : 'lisi',
 // 'age' : '18',
 // 'language' : [1,["二","三"],["四","五"]],
 //};
 console.log(obj3);
 //obj3 = {
 // 'name' : 'zhangsan',
 // 'age' : '20',
 // 'language' : [1,["二","三"],["四","五"]],
 //};

2.1浅拷贝

数组常用的浅拷贝方法有slice(),concat(),Array.from(),以及es6的解构

var arr1 = [1, 2,{a:1,b:2,c:3,d:4}];
var arr2 = arr1.slice();
var arr3 = arr1.concat();
var arr4 = Array.from(arr1);
var arr5 = [...arr1];
arr2[0]=2;
arr2[2].a=2;
arr3[0]=3;
arr3[2].b=3;
arr4[0]=4;
arr4[2].c=4;
arr5[0]=5;
arr5[2].d=5;
// arr1[1,2,{a:2,b:3,c:4,d:5}]
// arr2[2,2,{a:2,b:3,c:4,d:5}]
// arr3[3,2,{a:2,b:3,c:4,d:5}]
// arr4[4,2,{a:2,b:3,c:4,d:5}]
// arr5[5,2,{a:2,b:3,c:4,d:5}]

对象常用的浅拷贝方法Object.assign(),es6解构

var obj1 = {
 x: 1, 
 y: {
 m: 1
 }
};
var obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: {m: 1}}
console.log(obj2) //{x: 1, y: {m: 1}}
obj2.x=2;
obj2.y.m = 2; //修改obj2.y.m
console.log(obj1) //{x: 1, y: {m: 2}}
console.log(obj2) //{x: 2, y: {m: 2}}

我们自己实现一个浅拷贝

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
var shallowCopy = function(obj) {
 // 只拷贝对象
 if (typeof obj !== 'object') return;
 // 根据obj的类型判断是新建一个数组还是对象
 var newObj = obj instanceof Array ? [] : {};
 // 遍历obj,并且判断是obj的属性才拷贝
 for (var key in obj) {
 if (obj.hasOwnProperty(key)) {
 newObj[key] = obj[key];
 }
 }
 return newObj;
}

2.2. 深拷贝

比较简单粗暴的的做法是使用JSON.parse(JSON.stringify(obj))

var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
var new_arr = JSON.parse( JSON.stringify(arr) );
new_arr[4].old=4;
console.log(arr); //['old', 1, true, ['old1', 'old2'], {old: 1}]
console.log(new_arr); //['old', 1, true, ['old1', 'old2'], {old: 4}]

JSON.parse(JSON.stringify(obj)) 看起来很不错,不过 MDN文档 的描述有句话写的很清楚:

undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。

但是在平时的开发中JSON.parse(JSON.stringify(obj))已经满足90%的使用场景了。

下面我们自己来实现一个

var deepCopy = function(obj) {
 if (typeof obj !== 'object') return;
 var newObj = obj instanceof Array ? [] : {};
 for (var key in obj) {
 if (obj.hasOwnProperty(key)) {
 newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
 }
 }
 return newObj;
}

3. 参数的传递

所有的函数参数都是按值传递。也就是说把函数外面的值赋值给函数内部的参数,就和把一个值从一个变量赋值给另一个一样;

  • 基本类型
var a = 2;
function add(x) {
 return x = x + 2;
}
var result = add(a);
console.log(a, result); // 2 4
  • 引用类型
function setName(obj) {
 obj.name = 'laowang';
 obj = new Object();
 obj.name = 'Tom';
}
var person = new Object();
setName(person);
console.log(person.name); // laowang

很多人错误地以为在局部作用域中修改的对象在全局作用域中反映出来就是说明参数是按引用传递的。

但是通过上面的例子可以看出如果person是按引用传递的最终的person.name应该是Tom。

实际上当函数内部重写obj时,这个变量引用的就是一个局部变量了。而这个变量会在函数执行结束后销毁。(这是是在js高级程序设计看到的,还不是很清楚)

4. 判断方法

基本类型用typeof,引用类型用instanceof

特别注意typeof null是"object", null instanceof Object是true;

console.log(typeof "Nicholas"); // "string"
console.log(typeof 10); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"
var items = [];
var obj = {};
function reflect(value){
 return value;
}
console.log(items instanceof Array); // true;
console.log(obj instanceof Object); // true;
console.log(reflect instanceof Function); // true;

Object.prototype.toString.call([]).slice(8, -1)有兴趣的同学可以看一下这个是干什么的

5. 总结

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码