【JS基础入门】JavaScript基础之值与引用传递、模板字面量、解构赋值、this指向、访问器属性、流程控制等知识点笔记

您所在的位置:网站首页 javascript引用值 【JS基础入门】JavaScript基础之值与引用传递、模板字面量、解构赋值、this指向、访问器属性、流程控制等知识点笔记

【JS基础入门】JavaScript基础之值与引用传递、模板字面量、解构赋值、this指向、访问器属性、流程控制等知识点笔记

#【JS基础入门】JavaScript基础之值与引用传递、模板字面量、解构赋值、this指向、访问器属性、流程控制等知识点笔记| 来源: 网络整理| 查看: 265

【JS基础入门】JavaScript基础之值与引用传递、模板字面量、解构赋值、this指向、访问器属性、流程控制等知识点笔记2021年04月03日 11:58:56阅读数:518博客 /  一纸荒凉* Armani/ JavaScript值传递与引用传递

区别很明显,值传递是不会改变实际的参数数值,而引用传递是可以改变参数的实际数值的,还有值传递是基本类型的传递,引用传递是对基本类型进行了封装之后再传递。

值类型(基本类型):String,Number,Boolean,Null,Undefined。引用类型:Array、Object、Function、Date等有多个值构成的可变长度的复杂类型。

1、按值传递值传参针对基本类型,引用传参针对引用类型,传参可以理解为复制变量值。基本类型复制后俩个变量完全独立,之后任何一方改变都不会影响另一方;

let num1 = 5;let num2 = num1;console.log(num1,num2); // 5 5num1 = 6;console.log(num1,num2); // 6 5

因为是按值传递的,传递完后俩个变量各不相干!

function addTen(num) { num += 10; return num;}var count = 20;var result = addTen(count); //按值传递 num = countalert(count); // 20, 没变化alert(result); // 30

2、引用传递引用传递适用于引用类型,object,array,function引用类型复制的是引用(即指针),之后的任何一方改变都会映射到另一方。

// 创建object对象const obj1 = { name: 'zhang', email: '123@qqcom', cal: '110'};const obj2 = obj1;console.log(obj1,obj2);// {name: "zhang", email: "123@qqcom", cal: "110"}// {name: "zhang", email: "123@qqcom", cal: "110"}// 对象使用点语法访问内部成员obj1.name = 'shuai';console.log(obj1,obj2);// {name: "shuai", email: "123@qqcom", cal: "110"} // {name: "shuai", email: "123@qqcom", cal: "110"}console.log(obj1 === obj2); // true

3、函数传参都是值传递传参不管是基本类型还是引用类型永远是值传递

function setName(obj) { obj.name = "Nicholas";}var person = new Object();setName(person); // obj = personalert(person.name); // "Nicholas" 看起来是按引用传递,但千万不要以为是按引用传递~~~

 当 var person = new Object(); 时,可以用下图表示变量和对象的关系:

 当调用函数 setName(person); 时,下图可以表示全局变量person和局部变量obj的关心:

 以上代码中创建一个对象,并将其保存在变量person中。然后,这个变量被传递到setName(obj)函数中之后就被复制给了obj。在这个函数内部,obj和person引用的是同一个对象。换句话说,即使ECMAScript说这个变量是按值传递的,但obj也会按引用来访问同一个对象。于是,在函数内部为obj添加name属性后,函数外部的person也将有所反应;因为这时的person和obj指向同一个堆内存地址。所以,很多人错误的认为:在局部作用域中修改的对象会在全局对象中反映出来,就说明参数是按引用传递的。

 为了证明对象也是按值传递的,我们再来看看下面这个经过修改的例子:

function setName(obj) { obj.name = "Nicholas"; obj = new Object(); //改变obj的指向,此时obj指向一个新的内存地址,不再和person指向同一个 obj.name = "Greg";}var person = new Object();setName(person); //你看看下面,相信我也是按值传递的了吧alert(person.name); //"Nicholas"

 当创建obj对象 obj = new Object(); 时,来看看这时person和obj的关系图:

这个例子与前一个唯一的区别,就是setName()函数中添加了两行代码: obj = new Object(); 用来改变obj的指向; obj.name = “Greg”; 用来给新创建的obj添加属性。如果是按引用传递的,那么person就会自动被修改为指向新创建的obj的内存地址,则person的name属性值被修改为”Greg”

函数参数传递按值类型还是引用类型?

基本类型参数的传递与基本类型的复制一样,传递的是变量值。

function addTen(num) { num = num + 10; return num;}var count = 20;var result = addTen(count);console.log(count); // 20console.log(result); // 30

引用类型参数的传递与引用类型的复制一样,传递的是内存地址。

function setName(obj){ obj.name = 'xxx'; obj = {name: 'ppp'}; // obj指向一个新的地址,与person不再指向同一个地址 console.log(obj.name); // 'ppp'}const person = {name : 'oo'};setName(person);console.log(person.name); // ‘xxx’

官方解释来一发:

ECMAScript中所有函数的参数都是按值传递的。

也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型的传递如同基本类型的复制一样,而引用类型值的传递,如同引用类型变量的复制一样。

总结

很简单,javascript函数参数都是按值传递(都是栈内数据的拷贝)。 基本类型传的是值本身(因为直接把值存在栈内),引用类型传的是对象在内存里面的地址 (因为复杂对象存在堆内,所以在栈里存对象所在的堆地址)。

模板字面量与标签函数

模板字面量是增强版的字符串,它用反引号标识模板字面量:将插值表达式嵌入到字符串中

let message = `Hello world!`; console.log(message); // "Hello world!"console.log(typeof message); //"string"console.log(message.length);// 12

模板字面量看上去仅仅是普通JS字符串的升级版,但二者之间真正的区别在于模板字面量的变量占位符。变量占位符允许将任何有效的JS表达式嵌入到模板字面量中,并将其结果输出为字符串的一部分变量占位符由起始的 ${ 与结束的 }来界定,之间允许放入任意的JS 表达式。最简单的变量占位符允许将本地变量直接嵌入到结果字符串中

普通字符串拼接

let name = "Nicholas",message = "Hello,"+name;console.log(message); // "Hello, Nicholas"

使用模板字面量

let name = "Nicholas",message =`Hello, ${name}`;console.log(message); // "Hello, Nicholas"

占位符 ${name} 会访问本地变量name,并将其值插入到message字符串中。message变量会立即保留该占位符的结果既然占位符是JS表达式,那么可替换的就不仅仅是简单的变量名。可以轻易嵌入运算符、函数调用等

let count = 10, price = 0.25, message = `${count} items cost $${(count * price).toFixed(2)}.`;console.log(message); // "10 items cost $2.50."function fn() { return "Hello World";}console.log(`foo ${fn()} bar`); // foo Hello World bar

利用模板字面量动态生成HTML菜单注意:利用传统的方式拼接HTML非常麻烦,这里使用模板字面量非常高效,在反引号中可以随意书写HTML代码且有提示和高亮,按照标签结构可随意换行进行显示。

let list = ["汽车", "电脑", "水果"]; let str = ""; list.forEach(function (item) { str += "" + item + ""; }); console.log(str); const ul = document.createElement("ul"); ul.innerHTML = str; document.body.appendChild(ul); // 创建一个数组存放导航菜单let menus = ['首页','视频','文章','留言','登录'];// 利用模板字面量创建html代码let htmlStr = ` ${menus[0]} ${menus[1]} ${menus[2]} ${menus[0]} ${menus[4]}`;console.log(htmlStr);// 将HTML代码插入到body之后document.body.insertAdjacentHTML('beforeEnd',htmlStr);

标签模板(标签函数)

模板字面量真正的威力来自于标签模板,每个模板标签都可以执行模板字面量上的转换并返回最终的字符串值。标签指的是在模板字面量第一个反引号前方标注的字符串

let tag = (ms)=>alert(ms);//传统调用方式tag('Hello world');//用标签模板来调用它tag`Hello world`; //标签模板:模板字面量前是一个标识符,本质上是一个函数 //所以,我们可以认为标签模板是函数调用的特殊形式 //函数名:模板字面量前面的标识符 //调用参数:标签后面的模板字面量

tag 就是应用到Hello world模板字面量上的模板标签

标签可以是一个函数,调用时传入加工过的模板字面量各部分数据,但必须结合每个部分来创建结果。第一个参数是一个数组,包含Javascript解释过后的字面量字符串,它之后的所有参数都是每一个占位符的解释值

标签函数通常使用不定参数特性来定义占位符,从而简化数据处理的过程

function tag(literals, ...substitutions) { // 返回一个字符串}

为了进一步理解传递给tag函数的参数,查看以下代码

let count = 10, price = 0.25, message = passthru`${count} items cost $ ${(count * price).toFixed(2)}.`;

如果有一个名为passthru()的函数,那么作为一个模板字面量标签,它会接受3个参数首先是一个literals数组,包含以下元素 1、第一个占位符前的空字符串(“”) 2、第一、二个占位符之间的字符串(“items cost $”) 3、第二个占位符后的字符串(“.”)

下一个参数是变量count的解释值,传参为10,它也成为了substitutions数组里的第一个元素

最后一个参数是(count*price).toFixed(2)的解释值,传参为2.50,它是substitutions数组里的第二个元素

var a = 5;var b = 10;tag`Hello ${ a + b } world ${ a * b }`; // 等同于tag(['Hello ', ' world ', ''], 15, 50);

通过这种模式,我们可以将literals和substitutions两个数组交织在一起重组结果字符串。先取出literals中的首个元素,再取出substitution中的首个元素,然后交替继续取出每一个元素,直到字符串拼接完成。于是可以通过从两个数组中交替取值的方式模拟模板字面量的默认行为

function passthru(literals, ...substitutions) { let result = ""; // 仅使用 substitution 的元素数量来进行循环 for(let i = 0; i { console.log(strs); // console.log(`${s[0]}+${s[1]}=${s[2]}`); console.log(`${strs[0]}${args[0]}${strs[1]}${args[1]}${strs[2]}${args[2]}${strs[3]}`);}let a=3,b=2;sum`${a}+${b}=${a+b}`;

这里我们看到了,第一个参数是由所有的字符串字面量组成的数组,后面是插值表达式的值

String.raw方法,往往用来充当模板字面量的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字面量如果原字符串的斜杠已经转义,那么String.raw不会做任何处理

String.rawHi\n// "Hi\\n"

“标签模板”的一个重要应用,就是过滤HTML字符串,防止用户输入恶意内容

var message = SaferHTML` ${sender} has sent you a message.`;function SaferHTML(templateData) { var s = templateData[0]; for(vari = 1; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3