Loading

js中特殊的name属性

特殊的name属性

今天在学习变量提升与函数提升遇到了这样一个问题,在进行变量提升的代码测试的时候,我习惯性的使用我常用的变量申明

// 变量提升测试
console.log(name) // 根据所学的变量提升的知识,我原本以为输出的结果是undefined
var name = 'Fitz' // 常用的变量申明

实际上的结果是输出一个空的字符串

当时的我就觉得很纳闷,那既然这样,我们一上来先看看window对象的状况

果不其然,window对象在页面一创建时,就有一个(申明)name属性

name属性的默认值是一个空的字符串

在搞清楚为什么引发了变量提升代码测试的结果这么奇怪后,我们就来了解一下这个name属性和它究竟有什么作用的吧

根据菜鸟教程中对name属性的解释是这样的:

name 属性可设置或返回存放窗口的名称的一个字符串

给大家出一道题,大家猜猜结果

var name = 123
var obj = {}
console.log(123 + name + obj)   // 猜猜输出是啥

有人可能会回答NaN,基础比较好的人可能回答246[object Object]

其实真正的答案是123123[object Object]

我们来分析一下出现三种结果的原因吧

首先我们回顾js基础知识中的+运算符的相关知识

// +运算符除了可以将两个值相加
// 还可以将一个值取正(一元运算符)
// 最重要的是还能与字符创拼串

var a = 1
var b = 2
var str = 'hello'
console.log(a + b)  // 将两个值相加
console.log(+a)     // 一元运算符+对于数字毫无作用
console.log(+str)     // NaN 一元运算符+对字符串却能够隐式转换成Number类型

console.log(a + str)    // '1hello' 进行拼串

回答NaN的人可能遗忘了js基础中+运算符的特殊

var name = 123
var obj = {}
console.log(123 + name)         // 抛开name的特殊,暂定结果为: 246 

// 认为是NaN的人,可能想 Number类型 - Object类型 = NaN, 那+的结果自然如此,但结果并不是这样
console.log(1 - obj)    // NaN

// Number类型数据 + Object类型数据
// 结果是: Object类型数据会先toString()成字符串,然后与Number类型数据进行拼串
console.log(246 + obj)          // 246[object Object]

回答246[object Object]的人,基础知识较牢固,但是仍摸不到正确答案,究其原因就是出现在了这个特殊的name属性上了

var name = 123
// 猜猜结果是啥
console.log(typeof name)    // 结果是 string 而不是 number

所以回答246[object Object]的人,只是没有弄清这个name属性
name属性不管取啥值都会被自动使用类似toString()方法转换成其字符串表示

var name = {}
var obj = {}
console.log(name)           // [object Object]
console.log(obj.toString()) // [object Object]
name = true
console.log(name)           // 'true'

最终答案是123123[object Object]的全过程是

var name = 123
var obj = {}
console.log(123 + name)         // 123123 => 123 + '123'
console.log(123 + name + obj)   // 123123[object Object] => 123123 与 {} 拼串操作

通过一道题了解完name属性后,就来了解一下它有什么用

我们可以通过name属性实现跨页面,甚至跨域获取数据

创建第一个页面用于传递数据

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<body>
    <a href="./使用name属性,实现跨域获取数据.html" target='被跨域读取的数据' id="link">点我跳转页面</a>
    <script>
        // 使用name属性,实现跨域获取数据
        const link = document.getElementById('link')
        // 要通过跨域传播的数据
        var data = ' 加上这些data...'
        data = link.getAttribute('target') + data
        link.setAttribute('target', data)
    </script>
</body>
</html>

创建第二个页面用于接收数据

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<body>
    <h1>接收到来自跨域传播的数据: </h1>
    <p id="data"></p>
    <script>
        const p = document.getElementById('data')
        // 此时window.name就能得到由target传过来的数据了
        p.innerText = window.name
        console.log(window.name)
    </script>
</body>
</html>

posted @ 2021-02-28 22:55  虚伪渲染敷衍  阅读(665)  评论(0编辑  收藏  举报