手写递归深拷贝,必会的

<script>// 定义一个嵌套深的对象,深拷贝let obj = {name: '张三',list: [1, 2, 3]}//判断是否是基本数据类型,如果是直接return,因为复杂数据类型才会深拷贝function deepClone(obj) {//判断是否是基本数据类型,nul也是基本数据类型if (typeof obj !== 'object' || obj == null) {return obj}//初始化判断是数组还是对象 初始化返回结果let resultif (obj instanceof Array) {result = []} else {result = {}}//for in 循环,数组和对象有原型,空的也有,没必要去拿obj原型上的方法或属性for (let key in obj) {//排除原型上的方法或属性 hasOwnProperty判断是否是自己私有属性if (obj.hasOwnProperty(key)) {result[key] = deepClone(obj[key]) //递归调用}}return result}console.log(obj); //{name: '张三', list: Array(3)}let newObj = deepClone(obj)console.log(newObj); //{name: '张三', list: Array(3)}// 检测一下深拷贝是否成newObj.name = '李四'console.log(newObj); //{name: '李四', list: Array(3)}  ok 关机下班
</script>

  • 简单的东西必会的,抽象的允许你有瑕疵

  • 开始

一、数据类型

1. JavaScript有哪些数据类型,它们的区别?

JavaScript共有八种数据类型,分别是 Number、String、Boolean、Undefined、Null、Object、Symbol、BigInt。

其中 Symbol 和 是ES6 中新增的数据类型:BigInt 是es10新增

  • Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。

  • BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。

这些数据可以分为原始数据类型和引用数据类型:

  • 栈:原始数据类型(Number、String、Boolean、Undefined、Null , Symbol, BigInt)

  • 堆:引用数据类型(对象、数组和函数)

两种类型的区别在于存储位置的不同:

  • 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;

  • 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。

堆和栈的概念存在于数据结构和操作系统内存中,在数据结构中:

  • 在数据结构中,栈中数据的存取方式为先进后出。

  • 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。

在操作系统中,内存被分为栈区和堆区:

  • 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

  • 堆区内存一般由开发着分配释放,若开发者不释放,程序结束时可能由垃圾回收机制回收。

2. 数据类型检测的方式有哪些

(1)typeof只能正确判断基本数据类型,其中数组、对象、null都会被判断为object,其他判断都正确。

console.log(typeof 2);               // number===》Number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object
console.log(typeof function(){});    // function
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object 因为在浏览器中对象存储是000的二进制数,null也是
console.log(typeof {});              // object

(2)instanceof ------------------------- 被检测 instanceof 类型 (空格隔开)

instanceof只能正确判断引用数据类型,判断原型链中能否找到该类型的原型。而不能判断基本数据类型它返回值是布尔值fasle

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false
console.log('str' instanceof String);                // false console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

可以看到,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。instanceof 运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。基本数据类型返回布尔值false,因为它是判断判断原型链中能否找到该类型的原型

constructor有两个作用,一是判断数据的类型,用法:(被检测).constructor===类型,

但是它不能创建一个对象来改变它的原型,constructor就不能用来判断数据类型了

每一个对象里都有一个prototype,里面有一个 constructor指针,指向构造函数事例本身

(3) constructor 要加()不然会以为是小数,所以加()

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

实例化对象的变量通过 constrcutor 对象访问它的构造函数。判断实例化对象是不是构造函数的实例化对象,返回一个布尔值

需要注意,如果创建一个对象来改变它的原型或指针,constructor就不能用来判断数据类型了:

//定义构造函数
function Fn(name,age){this.name=namethis,age=age
};
//将Fn实例化一个变量
var f = new Fn();
//改变原型 对象变成数组
//如果创建一个对象来改变它的原型,`constructor`就不能用来判断数据类型了
Fn.prototype = new Array();
// false 这里应该是true,f是fn的事例实例对象,但是修改了原型导致`constructor`判断不正确
console.log(f.constructor===Fn);  // false 不能正确判断
console.log(f.constructor===Array); // true//第二个例子
<script>// 1 Person 构造函数 function Person(name, age) {this.age = age;this.name = name;this.run = function() {console.log('我叫' + this.name + '今年' + this.age + '我跑步可快了');}}var obj = new Person('张三', '23'); // 实例化对象 // new 创建对象 传参 // console.log(obj);// obj.run(); //实例过后才可以调方法和属性// 2 Person1 构造函数 function Person1(name, age) {this.age = age;this.name = name;}//1 篡改原型会导致`constructor`不能正确判断// Person1.prototype = Person.prototype//     // 再次指回来就可以正确判断// Person1.prototype.constructor = Person1// 2 篡改指针会导致`constructor`不能正确判断Person1.prototype.constructor = Person.prototype.constructorvar obj = new Person1('李四', '18');//这里应该是`true`,obj是Person1的实例化对象console.log(obj.constructor === Person1); //false  // 篡改指针导致constructor不能准确判断
</script>

(4)Object.prototype.toString.call()

Object.prototype.toString.call() 使用 Object 对象的原型方法 toString 来判断数据类型:

var a = Object.prototype.toString;console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?

这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

3. 判断数组的方式有哪些

  • 通过Object.prototype.toString.call()做判断

Object.prototype.toString.call(obj).slice(8,-1) === 'Array';
  • 通过原型链做判断
obj.__proto__ === Array.prototype;

没有js金刚钻 怎么,一步一步,一步斩获大厂offer相关推荐

  1. 五十步笑百步翻译软件测试,五十步笑百步

    五十步笑百步 (汉语成语) 语音 编辑 锁定 讨论 上传视频 五十步笑百步是一个汉语成语,读音为wǔ shí bù xiào bǎi bù,该成语用来比喻自己跟别人有同样的缺点或错误,只是程度上轻一些 ...

  2. 提升工作效率五步走之前两步 2016-09-18 思佳真探

    我03年毕业,工作也有13年了,也算个老司机了.中秋节那天,我找隔壁老王喝酒,我就问他,怎样工作才更有效率呢?老王趁着还没有喝多瞎逼逼,和我聊了如何迅速提升职场的工作效率,我挺佩服老王的牛逼,于是给老 ...

  3. 第30章 第7步到第10步:循环往复

    第30章 第7步到第10步:循环往复 LDLT法则 即学习=>实践=>掌握=>传授 第7步:开始学习,浅尝辄止 学习过程中最常犯的两类错误是什么? 第一类:行动太快,知之不多就盲目开 ...

  4. 经典运动估计算法之全搜索、三步搜索、四步搜索、菱形搜索

    全搜索算法 三步搜索算法 四步搜索算法 菱形搜索算法 由于搜索方法的不同,因此有多种运动估计算法,较为经典的运动估计搜索算法有全搜索法.三步搜索法.菱形搜索法以及四步搜索法等等.以下是几种运动估计搜索 ...

  5. 递归求解走台阶问题,一次可以走一步、两步、三步、...、n步(经典面试题——增强版走台阶)

    1.问题描述 现在有一个台阶,一共有n阶,你一次性可以走1步.2步.3步........n步.问:一共有多少种走法. 2.求解思路 第一步走1阶:那么这种情况下的走法数量和剩下n-1阶的走法数量有关: ...

  6. html+css+js 填写表单实现下一步上一步操作

     效果如下 完整代码如下 <!DOCTYPE html> <html> <head><meta charset="utf-8"> & ...

  7. c语言dht网络爬虫,用Node.js实现一个DHT网络爬虫,一步一步完成一个BT搜索引擎(一)...

    传统的Bittorrent服务 传统的BT服务是由两部份组成的,tracker服务和p2p服务,通过前者用户可以知道谁拥有资源,后者是通过前者向拥有资源的用户发起下载. Trackerless 目前在 ...

  8. TCP协议三步挥手与四步挥手

    关于TCP协议 TCP(Transmission Control Protocol, 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.与之对应的是UDP(User Datagram ...

  9. 反思走火入魔 急功近利:一步一步的做 一步一步的走 顺其自然 水到渠成

    有时候学知识的时候急于求成,心里预期超过规律所允许的进度,就会容易导致 气急败坏  走火入魔  焦虑不安 心里不安静 混乱不堪 要求多久做完没有坏处,产生坏处的急于完成的急切心情,会导致自己走火入魔. ...

最新文章

  1. 化学博士6次投毒同事,只因对方给自己安排工作太多....
  2. 为了边缘计算,亚马逊、谷歌、微软已正面交锋!
  3. InnoDB与MyISAM中的count(*)的执行效率比较
  4. 分布式文件系统—HDFS—IDEA的Hadoop可视化插件BigDataTools
  5. Angular html 页面里的井号 #
  6. Eureka自我保护机制
  7. dlibdotnet 人脸相似度源代码_使用dlib中的深度残差网络(ResNet)实现实时人脸识别 - supersayajin - 博客园...
  8. [置顶] c++播放Flash文件
  9. java流水号_Java生成流水号
  10. ionic基本命令行
  11. 借助Net-Speeder对服务器进行优化
  12. Junit Rule的使用
  13. 爱奇艺埋点投递治理实践
  14. STLINK : Warning: Connection to device 0x413 is lost
  15. 奶茶自由让人上头,95后为何钟爱这一杯甜蜜疗愈?
  16. linux提权参考方法
  17. 安卓Android源码——ipcamera-for-android
  18. flask加载网页时css美化效果加载不出来的解决方法
  19. 全面解读IDC经营许可证
  20. android 图片 生成视频,照片制作成视频的方案有吗?如何视频安卓手机视频编辑器将手机里的照片制作成视频...

热门文章

  1. Buildroot 介绍
  2. 【4-8】《XML与JSON》——XML、解析XML、SAX、DOM4J、XStream、JSON、Gson、Fastjson
  3. zipline中benchmarks.py源码分析
  4. 中维世纪Java一面
  5. 华院计算 | 他自己的生命游戏结束了,留给后人的数学游戏长存
  6. kafka原理图简介
  7. Linux的scp 命令使用方法
  8. linux 脚本scp用法,Linux scp命令用法及实例分享
  9. Wireshark的抓包和分析,看这篇就够了!
  10. ensp抓包分析ARP代理和TCP传输