ES6系列学习(2)

1.Arrow Function箭头函数

箭头函数好处:
1.简明的语法
2.可以隐式返回(删掉return,就是简写形式)
3.不绑定this

const numbers = [5,6,13,0,18,23];

const double = numbers.map( (number) => number*2 )

2.箭头函数this理解

const Jelly = {
	name:'Jelly',
	hobbies:['Coding','Sleeping','Reading'],
	printHobbies:function(){
		this.hobbies.map(function(hobby){
			console.log(this)   //这个function是单独函数,按照调用方式,此时this是window
			console.log(`${this.name} loves ${hobby}`);
		})
	}
}
Jelly.printHobbies();

//输出结果
loves Coding
loves Sleeping
loves Reading

针对上面我们可以这样写:

const Jelly = {
	name:'Jelly',
	hobbies:['Coding','Sleeping','Reading'],
	printHobbies:function(){
		var self = this;   //printHobbies作为方法调用,此时this指向为该Jelly对象,我们目的也是指向该对象
		this.hobbies.map(function(hobby){
			console.log(`${this.name} loves ${hobby}`);
		})
	}
}
Jelly.printHobbies();

//输出结果
Jelly loves Coding
Jelly loves Sleeping
Jelly loves Reading

ES6中可以适用箭头函数解决这种Hack手段(因为箭头函数中this值继承他的父作用域):
之前this值是运行时动态指定的,箭头函数的this值是词法作用域,也就是被定义时就被指定的,不会随调用方法的改变而改变。

const Jelly = {
	name:'Jelly',
	hobbies:['Coding','Sleeping','Reading'],
	printHobbies:function(){
		this.hobbies.map((hobby) => {
			console.log(`${this.name} loves ${hobby}`);
		})
	}
}
Jelly.printHobbies();

//输出结果
Jelly loves Coding
Jelly loves Sleeping
Jelly loves Reading

3.参数默认值

function add(a=5,b=3){
	return a+b; 
}

add(,3)   //报错
add(2,3)   //5
add(undefined,3) //8

4.箭头函数不适应场景

//1.作为构造函数,或一个方法需要绑定到对象
const Person = (name,points) => {
	this.name = name;
	this.points = points;
}
//会报错 Person is not a constructor(不能使用箭头函数,要使用原始函数定义)
const Jelly = new Person('jelly',5);
当使用new生成一个实例的时候,会有4步:
1.创建一个空对象ibj
2.构造函数的this值指向新生成的对象obj
3.对象obj绑定构造函数原型对象
4.返回新生成的对象obj

Person.prototype.updatePoints = () => {
	this.points++;
	console.log(this.points)
}
//报错(因为箭头函数this值是父级,所以此时this值是Window,没有points属性,也要使用原始函数定义)
Jelly.updatePoints()
NaN

//2.当你真的需要this的时候
const button = document.querySelector('.zoom');
button.addEventListener('click',() => {
	this.classList.add('in');
	setTimeout(() => {
		this.classList.remove('in');
	},2000)
})

改成下面这样(这样箭头函数的this就会继承父级this,也就是button)
const button = document.querySelector('.zoom');
button.addEventListener('click',function() {
	this.classList.add('in');
	setTimeout(() => {
		this.classList.remove('in');
	},2000)
})
但是如果下面箭头函数也进行修改,如果我们改成这样(setTimeout里面this就是Window,因为是作为函数调用):
const button = document.querySelector('.zoom');
button.addEventListener('click',function() {
	this.classList.add('in');
	setTimeout(function() {
		this.classList.remove('in');
	},2000)
})


//3.需要使用arguments对象
//报错,因为箭头函数没有arguments
const sum = () => {
	return Array.from(arguments)
				.reduce((prevSum,value) 
				=>prevSum+value,0 )
}

构造函数和普通函数的区别:
1.对this的关联。内置this的值,取决于箭头函数在哪里定义,而非箭头函数执行的上下文环境。
2.new 不可用。箭头函数不能用new关键字来实例化对象,否则报错。
3.this指向不会改变。函数内置this指向不可改变,this在函数体内整个执行环境中为常量。有利于JavaScript引擎优化处理。
4.没有arguments对象。不能通过arguments对象访问传入的实参。只能使用显示命名或者其它新特性完成。

参考文章:
https://www.nowcoder.com/questionTerminal/e3e9b4e611cc4c6a9b175932d0b2bbcd
https://www.cnblogs.com/biubiuxixiya/p/8610594.html

Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。

参考文章:
https://www.cnblogs.com/jf-67/p/8440758.html

构造函数和new操作符

在JavaScript中,创建对象的方式包括两种:对象字面量和使用new表达式。

对象字面量是一种灵活方便的书写方式,例如:

var o1 = {
    p:”I’m in Object literal”,
    alertP:function(){
        alert(this.p);
    }
}

这种写法的缺点是,每创建一个新的对象都需要写出完整的定义语句,不便于创建大量相同类型的对象,不利于使用继承等高级特性。

new表达式是配合构造函数使用的,例如new String(“a string”),调用内置的String函数构造了一个字符串对象。下面我们用构造函数的方式来重新创建一个实现同样功能的对象,首先是定义构造函数,然后是调用new表达式:

function CO(){
    this.p = “I’m in constructed object”;
    this.alertP = function(){
        alert(this.p);
    }
}
var o2 = newCO();

那么,在使用new操作符来调用一个构造函数的时候,发生了什么呢?其实很简单,就发生了四件事:

var obj  ={};
obj.__proto__ = CO.prototype;
CO.call(obj);
return obj;

第一行,创建一个空对象obj。
第二行,将这个空对象的__proto__成员指向了构造函数对象的prototype成员对象,这是最关键的一步,具体细节将在下文描述。
第三行,将构造函数的作用域赋给新对象,因此CA函数中的this指向新对象obj,然后再调用CO函数。于是我们就给obj对象赋值了一个成员变量p,这个成员变量的值是” I’min constructed object”。
第四行,返回新对象obj。当构造函数里包含返回语句时情况比较特殊,这种情况会在下文中说到。

更多可以参考文章;
https://www.cnblogs.com/wangyingblog/p/5583825.html
https://www.cnblogs.com/alantao/p/5955911.html

Object.create和new Object

__proto__是什么?

每个对象都有一个[[prototype]}属性,这个属性是隐藏属性,谁创建了它,该属性就指向谁的prototype属性,因为是隐藏属性,不能直接访问,所以有的浏览器提供了一个__proto__属性来访问,然而这不是一个标准的访问方法,所以ES5中用Object.getPrototypeOf函数获得一个对象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一个对象的[[prototype]]

更多可以参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
https://www.cnblogs.com/94pm/p/9113434.html
https://blog.csdn.net/devincob/article/details/82021926

5.字符串模板

const person = 'Jelly';
const age = 5;
const sentence = ` ${person} is ${age * 5} years old.`

//字符串模板(更好的层级结构)
const template = `
	<div>
		<p>Hello</p>
	</div>
`;

//Vue中字符串模板
new Vue({
	template:`
		<div>
			<p>Hello</p>
		</div>
	`
})

看一个实例:

const Jelly = {
	todos:[
		{name:'Go to Store',complated:false},
		{name:'Watch Movie',complated:true},
		{name:'Running',complated:true}
	]
}

const template = `
	<ul>
		${Jelly.todos.map(todo => `
			<li>
				${todo.name} ${todo.complated ? `对`:`没完成`} 
			</li>
			`).join('')}
	</ul>
`

进一步改进:

在这里插入图片描述

6.标签模板

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

let message =
  SaferHTML`<p>${sender} has sent you a message.</p>`;
 
function SaferHTML(templateData) {
  let s = templateData[0];
  for (let i = 1; i < arguments.length; i++) {
    let arg = String(arguments[i]);
 
    // Escape special characters in the substitution.
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");
 
    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

上面代码中,sender变量往往是用户提供的,经过SaferHTML函数处理,里面的特殊字符都会被转义。

let sender = '<script>alert("abc")</script>'; // 恶意代码
let message = SaferHTML`<p>${sender} has sent you a message.</p>`;
 
message
// <p>&lt;script&gt;alert("abc")&lt;/script&gt; has sent you a message.</p>

2.标签模板的另一个应用,就是多语言转换(国际化处理)。

i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "欢迎访问xxx,您是第xxxx位访问者!"

标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。

function highlight(strings,...values){
	const v1 = strings[0];   //has commented on you topic
	const v2 = strings[1];   //etc
	const highlighted = values;
	highlighted[0];   //Mary
	highlighted[1];   //Learn to use markdown

	const str = valuse.map(value =>
		`<span>{value}</span>`
	)
	return str;   //返回给sentence
}

const user = 'Mary';
const topic = 'Learn to use markdown';
const sentence = highlight`${user} has commented on you topic ${topic} etc`

DOMPurify – 针对 HTML、MathML 和 SVG 的仅支持DOM、快速、高容错的 XSS 过滤器。

DOMPurify地址:https://github.com/cure53/DOMPurify

7.字符串模板中转义标签

就是上面的转义标签模板的第一个主要功能。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值