你不知道的16个js原生函数和属性的区别

文章详细解释了JavaScript中对象属性的几种获取方式(如Object.keys和Symbol),DOM节点的关系和操作(如Node.contains和compareDocumentPosition),以及字符串处理(如substr和substring)、函数调用方式(call,apply,bind)和文档可见性检查(hidden,visibilityState)。

console.log(“ownKeys”, ownKeys); // [ ‘age’, ‘name’, ‘walk’, ‘sex’, Symbol(salary) ]

console.log(“--------”)

console.log(person.isAnimal);  // true

console.log(person[symbolIsAnimal]); // true

console.log(person[symbolSalary]);  // 999

personsymbolSay; // symbolSay hello world

person.say(“hello world”); // say: hello world

person.walk(); // person:walk

复制代码

总结

  1. Object.keys:则返回的是所有可枚举属性键,也就是属性下的enumerable: true。但不包括Symbol值作为名称的属性键。

  2. Object.getOwnPropertyNames:返回的是对象所有自己的属性键 ,包括不可枚举属性但不包括Symbol值作为名称的属性键。

  3. Object.getOwnPropertySymbols: 方法返回一个给定对象自身的所有 Symbol 属性键的数组。

  4. Reflect.ownKeys: 返回一个由目标对象自身的属性键组成的数组。等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))。

节点位置关系 Node.containsNode.compareDocumentPosition


Node.compareDocumentPosition[7]

比较当前节点与任意文档中的另一个节点的位置关系

语法 compareMask = node.compareDocumentPosition( otherNode )

返回值是一个具有以下值的位掩码:

| 常量名 | 十进制值 | 含义 |

| — | — | — |

| DOCUMENT_POSITION_DISCONNECTED | 1 | 不在同一文档中 |

| DOCUMENT_POSITION_PRECEDING | 2 | otherNode在node之前 |

| DOCUMENT_POSITION_FOLLOWING | 4 | otherNode在node之后 |

| DOCUMENT_POSITION_CONTAINS | 8 | otherNode包含node |

| DOCUMENT_POSITION_CONTAINED_BY | 16 | otherNode被node包含 |

| DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | 32 | 待定 |

在一些场景下,可能设置了不止一位比特值。比如 otherNode 在文档中是靠前的且包含了 Node, 那么DOCUMENT_POSITION_CONTAINS 和 DOCUMENT_POSITION_PRECEDING 位都会设置,所以结果会是 0x0A 即十进制下的 10。

看代码:

结果是:20

  1. child 在 parent之后,赋值得4

  2. child 被 parent包含,赋值的16

4 + 16 = 20

复制代码

Node.contains[8]

返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点

基本等于compareDocumentPosition的 | DOCUMENT_POSITION_CONTAINED_BY | 16 |otherNode被node包含 |

总结

  1. compareDocumentPosition 返回的是数字,带组合意义的数据,不仅仅可以返回包含,还可以返回在之前之后等信息

  2. contains 返回的是布尔值,仅仅告诉你是否有包含关系

取文本 innerTexttextContent


HTMLElement.innerText[9]

解析过程:

  1. 对HTML标签进行解析;

  2. 对CSS样式进行带限制的解析和渲染;

  3. 将ASCII实体转换为对应的字符;

  4. 剔除格式信息(如\t、\r、\n等),将多个连续的空格合并为一个

Node.textContent[10]

解析过程:

  1. 对HTML标签进行剔除

  2. 将ASCII实体转换为相应的字符。

需要注意的是:

  1. 对HTML标签是剔除不是解析,也不会出现CSS解析和渲染的处理,因此<br/>等元素是不生效的。

  2. 不会剔除格式信息和合并连续的空格,因此\t、\r、\n和连续的空格将生效

例子

Take a look at
how this text
is interpreted

below.

HIDDEN TEXT

Result of textContent:

...

Result of innerText:

...

复制代码

看看结果:

image.png

总结

  1. innerText是会解析css的,<br/>有效,剔除格式信息(如\t、\r、\n等),将多个连续的空格合并为一个。

  2. textContent是剔除html标签,<br/>无效,\t、\r、\n和连续的空格将生效。

节点取值 value , nodeValue


Node.nodeValue[11]

  • 对于textcomment, 和 CDATA 节点来说, nodeValue返回该节点的文本内容.

  • 对于 attribute 节点来说, 返回该属性的属性值.

对应着下面表格的 nodeType的值 text 3,4,8

| 常量 | nodeType 值 | 描述 |

| — | — | — |

| Node.ELEMENT_NODE | 1 | 一个 元素 节点,例如 |

|| Node.TEXT_NODE | 3 | Element 或者 Attr 中实际的 文字 || Node.CDATA_SECTION_NODE | 4 | 一个 CDATASection,例如 <!CDATA[[ … ]]>。|| Node.PROCESSING_INSTRUCTION_NODE | 7 | 一个用于XML文档的 ProcessingInstruction (en-US) ,例如 声明。|| Node.COMMENT_NODE | 8 | 一个 Comment 节点。|| Node.DOCUMENT_NODE | 9 | 一个 Document 节点。|| Node.DOCUMENT_TYPE_NODE | 10 | 描述文档类型的 DocumentType 节点。例如 就是用于 HTML5 的。|| Node.DOCUMENT_FRAGMENT_NODE | 11 | 一个 DocumentFragment 节点 |

value

特定的一些HTMLElement元素,用value属性获取其值。常见的有value属性的元素如下:

  • HTMLInputElement[12] <input value="1" />

  • HTMLTextAreaElement[13] <textarea value= "你哈" />

  • HTMLButtonElement[14] <button value= "提交" />

  • HTMLDataElement[15] <data value="21053">圣女果</data>

  • HTMLSelectElement[16] <select><option value ="volvo">Volvo</option>

  • HTMLOptionElement[17] <select><option value ="volvo">Volvo</option>

  • HTMLParamElement[18]

    

复制代码

  • HTMLProgressElement[19] <progress value="22" max="100"></progress>

总结

  1. nodeValue 是文本节点,属性节点,注释节点等类型的节点用来取值的方法

  2. vlaue是特定的元素节点用来取值的方法

节点复制 adoptNodeimportNodecloneNode


Document.adoptNode[20]

将外部文档的一个节点拷贝一份,然后可以把这个拷贝的节点插入到当前文档中.

Document.importNode[21]

从其他的document文档中获取一个节点。该节点以及它的子树上的所有节点都会从原文档删除 , 并且它的ownerDocument 属性会变成当前的document文档。之后你可以把这个节点插入到当前文档中。

Node.cloneNode[22]

生成节点的一个副本。

实际上 Document 是继承自 Node, 也具备cloneNode方法。

这里提一个问题:

Document.adoptNodeDocument.importNode是操作外部文档的,那么操作所在的文档会有什么效果呢?

Node.cloneNode 有一个boolean类型的可选参数deep

  • true: 则该节点的所有后代节点也都会被克隆

  • false: 则只克隆该节点本身.

注意

  1. cloneNode deep参数在不同版本的浏览器实现中,默认值可能不一样, 所以强烈建议写上值。

  2. cloneNode 会克隆一个元素节点会拷贝它所有的属性以及属性值,当然也就包括了属性上绑定的事件(比如οnclick=“alert(1)”),但不会拷贝那些使用addEventListener()方法或者node.onclick = fn这种用JavaScript动态绑定的事件

总结

  1. adoptNode 从外部文档进行拷贝

  2. importNode 从外部文档进行拷贝,并从外部文档删除

  3. cloneNode 从本文档进行复制,有浅复制和深复制

父节点 childNodes , children


Node.childNodes[23]

节点的子节点集合,包括元素节点、文本节点还有属性节点

ParentNode.children[24]

返回的只是节点的元素节点集合, 即 nodeType为1的节点。

例子

来实际看一段代码:

1

2

3

<!CDATA[[ 4 ]]>

复制代码

返回结果截图:

Node.parentNodeNode.parentElement也是同样的道理。

总结

  1. children只返回元素节点,也就是 nodeType为1的节点

  2. childNodes 返回所有类型的节点

添加节点 appendappendChild


node.appendChild[25]

将一个节点附加到指定父节点的子节点列表的末尾处

ParentNode.append[26]

方法在 ParentNode的最后一个子节点之后插入一组 Node 对象或 DOMString 对象。被插入的 DOMString 对象等价为 Text 节点.

例子

我们一次append三个节点,其中两个文本节点,一个div节点。

复制代码

image.png

总结

  • ParentNode.append()允许追加 DOMString 对象,而 Node.appendChild() 只接受 Node 对象。

  • ParentNode.append() 没有返回值,而 Node.appendChild() 返回追加的 Node 对象。

  • ParentNode.append() 可以追加多个节点和字符串,而 Node.appendChild() 只能追加一个节点。

简直说, append强大太多了。

文档可见状态 Document.hiddenDocument.visibilityState


document.hidden[27]

返回布尔值,表示页面是(true)否(false)隐藏。

Document.visibilityState[28]

返回document的可见性, 由此可以知道当前文档(即为页面)是在背后, 或是不可见的隐藏的标签页,或者(正在)预渲染.可用的值如下:

  • ‘visible’ : 此时页面内容至少是部分可见. 即此页面在前景标签页中,并且窗口没有最小化.

  • ‘hidden’ : 此时页面对用户不可见. 即文档处于背景标签页或者窗口处于最小化状态,或者操作系统正处于 ‘锁屏状态’ .

  • ‘prerender’ : 页面此时正在渲染中, 因此是不可见的 . 文档只能从此状态开始,永远不能从其他值变为此状态 .注意: 浏览器支持是可选的.

当此属性的值改变时, 会递交 visibilitychange 事件给Document.

例子

我们先输出当前状态,然后点击别的tab,等下再点击回来。

console.log(

“visibilityState:”,

document.visibilityState,

" hidden:",

document.hidden,

);

console.log(“”);

document.addEventListener(“visibilitychange”, function () {

console.log(

“visibilityState:”,

document.visibilityState,

" hidden:",

document.hidden

);

});

复制代码

image.png

我们日常可以用visibilitychange来监听当前页面处于隐藏时,去清除定时器或页面中的动画, 停止音乐视频等的播放。

我还想到一个有意思的

  1. 广告倒计时

你离开后,不算倒计时,会不会被骂死

  1. 阅读某些协议

你离开后,停止倒计时

总结

  1. hidden 与 visibilityState 返回值不同,一个是布尔值,一个是字符串

  2. visibilityState 的状态多一种 prerender, 其对应的hidden的值是true

  3. visibilityState e有相关的事件

函数调用 callapplybind


Function.prototype.call[29]

使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数

Function.prototype.apply[30]

调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数

Function.prototype.bind[31]

方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用

例子

function sum(…args) {

const total = args.reduce((s, cur) => {

return s + cur;

}, 0);

return (this.base || 0) + total;

}

const context = {

base: 1000

};

const bindFun = sum.bind(context, 1, 2);

const callResult = sum.call(context, 1, 2, 3, 4);

const applyResult = sum.apply(context, [1, 2, 3, 4]);

const bindResult = bindFun(3, 4);

console.log(“call:”, callResult);  // 1010

console.log(“apply:”, applyResult); // 1010

console.log(“bind:”, bindResult); // 1010

复制代码

总结

相同点,都能改变被调用函数的this指向。

  1. call: 第二个参数开始,可以接收任意个参数

  2. apply: 第二个参数,必须是数组或者类数组

  3. bind: 第二个参数开始,可以接收任意个参数 , 返回的是一个新的函数

注意点:

  1. bind调用多次,this指向第一次第一个参数

log 调用了两次bind, 第一次bind{ val: 1 }, 第二次bind{ val: 2 }, 输出的this是一次bind的上下文

function log() {

console.log(“this”, this);

}

console.log(log.bind({ val: 1 }).bind({ val: 2 })())  // { val: 1 }

复制代码

再看一段类似的代码:

虽然this的指向不会再变改变,但是参数还是继续接受, arguments 长度为2, 第一次bind的1,第二次bind的 2 , 都照单全收。

function log() {

console.log(“this”, this);   // { val: 1 }

console.log(“arguments”, arguments);  // { ‘0’: 1, ‘1’: 2 }

}

console.log(log.bind({ val: 1 }, 1).bind({ val: 2 }, 2)())  // 1

复制代码

字符串截取 substrsubstring


String.prototype.substr[32]

返回一个字符串中从指定位置开始到指定字符数的字符

语法:第二参数,是需要截取的长度

str.substr(start[, length])

String.prototype.substring[33]

返回一个字符串在开始索引到结束索引之间的一个子集, 或从开始索引直到字符串的末尾的一个子集。

语法:第二参数,结束索引

str.substring(indexStart[, indexEnd])

例子

提示:

两个参数都没设置的时候,效果相同

第一个参数是大于等于0的整数,没设置第二参数的时候,效果相同

const str = “我们都是好孩子”;

console.log(str.substr())  // 我们都是好孩子

console.log(str.substring()) // 我们都是好孩子

console.log(str.substr(1))  // 们都是好孩子

console.log(str.substring(1)) // 们都是好孩子

console.log(str.substr(-1))  // 子

console.log(str.substring(-1)) // 我们都是好孩子

console.log(str.substr(1, 2))  // 们都

console.log(str.substring(1, 2))  // 们

复制代码

总结

  1. substr 第二个参数是需要截取的长度

  2. substring 第二个参数是结束索引值的

  3. 没指定参数或者第一个参数是大于等于0的整数时,效果相同

  4. 第一个参数是负数或者第二个参数是负数,处理规则不通

具体参见 substr[34]和 substring[35]

遍历 for offor in


for in

获取enumerable:true的属性键

for of

遍历属性值。不受到enumerable限制。

例子

在数组原型上增加了方法gogo, for in结果中出现了,而 for of结果冲未出现。

定义了 属性2不能被遍历, for in结果中未出现,而 for of结果中出现了。

// 原型上增加方法

Array.prototype.gogo = function(){

console.log(“gogo”);

}

var a = [1,2,3];

// key值2不可以枚举

Object.defineProperty(a, 2, {

enumerable: false

});

Object.defineProperty(a, “2”, {

enumerable: false

});

for(let p in a){

// 索引被遍历出来是字符串类型

console.log(p, typeof p); // 0 string; 1 string; gogo string

}

console.log(“—”)

for(let v of a){

console.log(v);  // 1 2 3

}

复制代码

总结

for in

  1. 获取enumerable:true的属性键。

  2. 可以遍历对象。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)


完整版面试题资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端实习面试的套路


回顾项目

往往在面试时,面试官根据你简历中的项目由点及面地展开问答,所以请对你做过的最好的项目进行回顾和反思。回顾你做过的工作和项目中最复杂的部分,反思你是如何完成这个最复杂的部分的。

面试官会重点问你最复杂的部分的实现方法和如何优化。重点要思考如何优化,即使你项目中没有对那部分进行优化,你也应该预先思考有什么优化的方案。如果这部分答好了,会给面试官留下很不错的印象。

重点在于基础知识

这里指的基础知识包括:前端基础知识和学科基础知识。

前端基础知识:html/css/js 的核心知识,其中 js 的核心知识尤为重要。比如执行上下文、变量对象/活动对象(VO/AO)、作用域链、this 指向、原型链等。

学科基础知识:数据结构、计算机网络、算法等知识。你可能会想前端不需要算法,那你可能就错了,在大公司面试,面试官同样会看重学生这些学科基础知识。
你可能发现了我没有提到React/Vue这些框架的知识,这里得说一说,大公司不会过度的关注这方面框架的知识,他们往往更加考察学生的基础。
这里我的建议是,如果你至少使用或掌握其中一门框架,那是最好的,可以去刷刷相关框架的面试题,这样在面试过程中即使被问到了,也可以回答个 7788。如果你没有使用过框架,那也不需要太担心,把重点放在基础知识和学科基础知识之上,有其余精力的话可以去看看主流框架的核心思想。

大家的负担。**

[外链图片转存中…(img-9IfB7wqe-1713669792237)]

[外链图片转存中…(img-4FVoMOYp-1713669792238)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-NSaR5sWu-1713669792238)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

[外链图片转存中…(img-5CphmUXN-1713669792238)]

完整版面试题资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端实习面试的套路


回顾项目

往往在面试时,面试官根据你简历中的项目由点及面地展开问答,所以请对你做过的最好的项目进行回顾和反思。回顾你做过的工作和项目中最复杂的部分,反思你是如何完成这个最复杂的部分的。

面试官会重点问你最复杂的部分的实现方法和如何优化。重点要思考如何优化,即使你项目中没有对那部分进行优化,你也应该预先思考有什么优化的方案。如果这部分答好了,会给面试官留下很不错的印象。

重点在于基础知识

这里指的基础知识包括:前端基础知识和学科基础知识。

前端基础知识:html/css/js 的核心知识,其中 js 的核心知识尤为重要。比如执行上下文、变量对象/活动对象(VO/AO)、作用域链、this 指向、原型链等。

学科基础知识:数据结构、计算机网络、算法等知识。你可能会想前端不需要算法,那你可能就错了,在大公司面试,面试官同样会看重学生这些学科基础知识。
你可能发现了我没有提到React/Vue这些框架的知识,这里得说一说,大公司不会过度的关注这方面框架的知识,他们往往更加考察学生的基础。
这里我的建议是,如果你至少使用或掌握其中一门框架,那是最好的,可以去刷刷相关框架的面试题,这样在面试过程中即使被问到了,也可以回答个 7788。如果你没有使用过框架,那也不需要太担心,把重点放在基础知识和学科基础知识之上,有其余精力的话可以去看看主流框架的核心思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值