JS 基础知识点及常考面试题(二) 您所在的位置:网站首页 js打印对象的属性是什么 JS 基础知识点及常考面试题(二)

JS 基础知识点及常考面试题(二)

2023-03-24 17:29| 来源: 网络整理| 查看: 265

1.== 和 === 有什么区别?

== 相等 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 会进行一次类型转换, 转换成相同类型后再进行比较。 1、如果两个值类型相同,进行 === 比较。 2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较: a、如果一个是null、一个是undefined,那么[相等]。 b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。 c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。 d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。非js核心的对象,另说(比较麻烦,我也不大懂) eg:[].toString() == '' ; [1,2].toString() == '1,2' e、任何其他组合,都[不相等]。

=== 绝对相等,即数据类型与值都必须相等。 (1)如果类型不同,就一定不相等   (2)如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)   (3)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。   (4)如果两个值都是true,或都是false,那么相等,否则不相等   (5)如果两个值都引用同一个对象或都是函数,那么相等,否则不相等   (6)如果两个值都是null,或都是undefined,那么相等,否则不相等

示例 console.log('10'==10); // true console.log('10'===10); // false console.log(null === undefined); // false console.log(null == undefined); // true console.log(null == 0); // false console.log(undefined == 0); // false console.log(typeof NaN); // number console.log(NaN == NaN); // false console.log(0 == "0"); // true console.log(true == "20"); // false console.log(true == "1" ); //true console.log([] == ![]); //true console.log({} == !{}); //false

注意:①NaN 不管 == === 都是false ②对于Array,Object等高级类型,==和===是没有区别的,会进行“指针地址”比较

eg: [] == [] //false

{} == {} //false

[1] == [1] //false

[1] === [1] //false

var a = [1] var c = a a==c //true a === c //true

[] == ! [] //true 为什么会是true

①、根据运算符优先级 ,! 的优先级是大于 == 的,所以先会执行 ![]

!可将变量转换成boolean类型,null、undefined、NaN以及空字符串('')取反都为true,其余都为false。

所以 ! [] 运算后的结果就是 false

也就是 [] == ! [] 相当于 [] == false

②、根据上面提到的规则(如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1),则需要把 false 转成 0

也就是 [] == ! [] 相当于 [] == false 相当于 [] == 0

③、根据上面提到的规则(如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较,如果对象没有valueOf()方法,则调用 toString())

而对于空数组,[].toString() -> '' (返回的是空字符串)

也就是 [] == 0 相当于 '' == 0

④、根据上面提到的规则(如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值)

Number('') -> 返回的是 0

相当于 0 == 0 自然就返回 true了

总结一下:

[] == ! [] -> [] == false -> [] == 0 -> '' == 0 -> 0 == 0 -> true

那么对于 {} == !{} 也是同理的

关键在于 {}.toString() -> [object Object]

总结一下:

{} == ! {} -> {} == false -> {} == 0 -> [object Object] == 0 -> false

2.闭包①什么是闭包

闭包是指有权访问另一个函数作用域内变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以 访问到当前函数的局部变量。

function A() { let a = 1 window.B = function () { console.log(a) } } A() B() // 1②循环中使用闭包解决 `var` 定义函数的问题for (var i = 1; i

在遇到函数、 undefined 或者 symbol 的时候,该对象也不能正常的序列化

let a = { age: undefined, sex: Symbol('male'), jobs: function() {}, name: 'yck' } let b = JSON.parse(JSON.stringify(a)) console.log(b) // {name: "yck"}

你会发现在上述情况中,该方法会忽略掉函数和 undefined 。

但是在通常情况下,复杂数据都是可以序列化的,所以这个函数可以解决大部分问题。

当然你可能想自己来实现一个深拷贝,但是其实实现一个深拷贝是很困难的,需要我们考虑好多种边界情况,比如原型链如何处理、DOM 如何处理等等,所以这里我们实现的深拷贝只是简易版

递归实现深拷贝思路:对属性中所有引用类型的值进行遍历,直到是基本类型值为止。

拓展:hasOwnProperty 作用是在一个对象里面找是否有某个属性或对象, 但是不会在它的原型中找, 返回boolean类型 一般用来过滤for in循环, 在for in循环中, 会遍历对象原型中的属性, 如果JS代码太多, 封装了一些组件, 大概就是模块化开发那种, 一个对象继承另一个对象, 你或许不知道这个对象继承了哪个对象, 就可以在遍历的时候用hasOwnProperty过滤了

var foo = {'a':1} foo.constructor.prototype.hi = 6 foo.__proto__.b = 2 Object.getPrototypeOf(foo).c = 3 for(var i in foo){ console.log('i :>> ', i); // a b hi c } for(var i in foo){ if(foo.hasOwnProperty(i)){ console.log('i :>> ', i); // a } }

在上面列子中,有涉及获取实列原型的三种方法

4.原型和原型链

如何理解原型?如何理解原型链?

当我们创建一个对象时 let obj = { age: 25 },我们可以发现能使用很多种函数,但是我们明明没有定义过它们,对于这种情况你是否有过疑惑?

当我们在浏览器中打印 obj 时你会发现,在 obj 上居然还有一个 __proto__ 属性,那么看来之前的疑问就和这个属性有关系了。

其实每个 JS 对象都有 __proto__ 属性,这个属性指向了原型。这个属性在现在来说已经不推荐直接去使用它了,这只是浏览器在早期为了让我们访问到内部属性 [[prototype]] 来实现的一个东西。

讲到这里好像还是没有弄明白什么是原型,接下来让我们再看看 __proto__ 里面有什么吧。

看到这里你应该明白了,原型也是一个对象,并且这个对象中包含了很多函数,所以我们可以得出一个结论:对于 obj 来说,可以通过 __proto__ 找到一个原型对象,在该对象中定义了很多函数让我们来使用。

在上面的图中我们还可以发现一个 constructor 属性,也就是构造函数

打开 constructor 属性我们又可以发现其中还有一个 prototype 属性,并且这个属性对应的值和先前我们在 __proto__ 中看到的一模一样。所以我们又可以得出一个结论:原型的 constructor 属性指向构造函数,构造函数又通过 prototype 属性指回原型,但是并不是所有函数都具有这个属性,Function.prototype.bind() 就没有这个属性。

我们再来看一张图,相信这张图能让你彻底明白原型和原型链

看完这张图,我再来解释下什么是原型链吧。其实原型链就是多个对象通过 __proto__ 的方式连接了起来。为什么 obj 可以访问到 valueOf 函数,就是因为 obj 通过原型链找到了 valueOf 函数。

对于这一小节的知识点,总结起来就是以下几点:

Object 是所有对象的爸爸,所有对象都可以通过 __proto__ 找到它Function 是所有函数的爸爸,所有函数都可以通过 __proto__ 找到它函数的 prototype 是一个对象对象的 __proto__ 属性指向原型, __proto__ 将对象和原型连接起来组成了原型链


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有