this的概念及指向问题:
this是Javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是调用函数的那个对象。
//1、作为普通函数调用,这时函数属于全局性调用,因此this就代表全局对象window
//普通函数
function fn() {
alert(this);
}
fn();
//函数表达式:将函数体赋值给变量
var fn1 = function () {
alert(this);
}
fn1();
//自执行函数
! function () {
alert(this);
}();
//定时器的函数
window.setTimeout(function () {
alert(this);
}, 0);
//回调函数:函数作为参数。
function fn2(callback) { //回调函数
callback(); //调用
}
fn2(function () {
alert(this);
});
//2、作为对象方法的调用,这时this就指这个当前对象。
//对象的方法
//事件处理函数
var obj = {
a: 100,
showa: function() {
alert(this.a); //100 this->obj -> obj.a=100
}
}
obj.showa();
document.onclick = function() {
alert(this); //[object HTMLDocument]
}
//3、作为构造函数调用,所谓构造函数,就是通过这个函数生成一个新对象(实例)。这时,this就指这个新对象(实例)。
//构造函数里面的this指向new出来的实例(实例对象)
function Person() {
alert(this); //this指向new出来的实例对象 p1 p2
}
var p1 = new Person(); //Person:构造函数(首字母大写,new调用)
var p2 = new Person(); //Person:构造函数(首字母大写,new调用)
改变this的指向 - apply 、 call 、bind的介绍(函数的方法)
函数对象的属性和方法
1.属性 - length:参数的个数
function fn(a, b, c, d) {
}
alert(fn.length);//4
2.函数的方法:apply,call,bind
apply 、 call 、bind 三者都是用来改变函数的this对象的指向.但是参数不一样。
//call参数:第一个参数代表this的指向,后面的参数就是函数自身的参数。
var num = 1;
var obj = {
num: 100,
shownum: function() {
alert(this.num);
}
}
obj.shownum();//100
obj.shownum.call(window);//1
//apply参数:第一个参数代表this的指向,后面的参数就是函数自身的参数,函数自身的参数放到一个数组中。
function sum(a, b) {
alert(this); //hehe
alert(a + b);
}
sum.call('hehe', 2, 4); //call参数:第一个参数代表this的指向,后面的参数就是函数自身的参数
sum.apply('hehe', [2, 4, 6, 8, 110, 2, 4, 6, 8, 110, 2, 4, 6, 8, 110])
//bind参数:和call参数一样,但是返回的是函数体,需要再次调用
function sum(a, b) {
alert(this); //hehe
alert(a + b);
}
sum.bind('hehe', 2, 4)();
JSON对象的介绍
JSON是前后端交互最好的数据格式。是一种轻量级的数据交换格式。它是基于 ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率.
JSON的特点:
json:是一种轻量级的数据交换格式。不是js独有的。
json组成:简单值+'对象'+'数组'
json里面字符串需要添加双引号。
json没有var关键字,没有分号(;)等js相关的语法
JSON的静态方法:
JSON.parse( ):用于从一个字符串中解析出json对象,具有json格式检测功能
var str = '{"name":"zhangsan","age":100,"sex":"男"}';
str = JSON.parse(str); //转换成对象。
console.log(str);
console.log(str.name); //zhangsan
var arr = '["zhangsan", "lisi", "wangwu"]';
arr = JSON.parse(arr);
console.log(arr[0]); //zhangsan
JSON.stringify( ):用于从一个对象解析出字符串,将对象转换成json格式的字符串
var obj = {
name: 'zhangsan',
age: 100,
sex: '男'
};
console.log(JSON.stringify(obj)); //'{"name":"zhangsan","age":100,"sex":"男"}'
eval() 函数
可以将对象格式的字符串转换成对象。将内部的字符串当做js代码进行解析;eval解析的时候两边添加圆括号,将解析的代码当成表达式,不会当做js代码执行
eval('var a = 1; var b = 2; alert(a+b);');//3
eval('[a=5];alert(a)');//5
var arr = "['zhangsan', 'lisi', 'wangwu']";
console.log(eval('(' + arr + ')')); //["zhangsan", "lisi", "wangwu"]
var str = "{'name':'zhangsan','age':100,'sex':'男'}";
console.log(eval('(' + str + ')')); //{name: "zhangsan", age: 100, sex: "男"}
对比JSON.parse和eval区别
JSON.parse具有json格式检测功能,安全性高于eval,eval将内部的字符串当成js代码执行
ES6介绍
let命令
用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。即let所声明的变量就“绑定”这个区域,不再受外部的影响。
全局:整个文档
局部:函数内部
块级:{}语句块内有效
{
let a = 10;
}
alert(a); //ReferenceError: a is not defined
for (let i = 1; i <= 5; i++) {
console.log(i);
}
alert(i); //ReferenceError: i is not defined
二.let和var的区别
1.let声明的不存在变量提升
alert(a);//报错,暂时性死区。
let a = 10;
alert(a); //10
2.let不允许在相同作用域内,重复声明同一个变量。
var a = 1;
var a = 2;
let b = 3;
let b = 4;//报错
let c = 10;
c = 100;//改变变量的值
var d = 1;
let d = 2; //报错
document.onclick = function(ev) { //var ev
let ev = ev || window.event; //报错
console.log(ev);
}
3.ES6允许块级作用域的任意嵌套,外层无法读取内层作用域的变量,反之可以
{
let a = 1;
{
console.log(a); //1
let b = 2;
}
console.log(b); //b is not defined
}
4.即let所声明的变量就“绑定”这个区域,不再受外部的影响。
var aLi = document.querySelectorAll('li');
for (let i = 0; i < aLi.length; i++) {
aLi[i].onclick = function() {
alert(i);
}
}
const常量
声明一个只读的常量,一旦声明,常量的值就不能改变;除了值不能改变之外,其他的特点和let一致的。
const a = 1;
a = 3;
alert(a); //报错
具体的应用场景:获取元素对象,普通函数
变量的解构赋值-快速的给变量赋值
从数组和对象中提取值,对变量进行赋值,这被称为解构
可以从数组中提取值,按照位置的对应关系对变量赋值.
本质上,这种写法属于模式匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值
//1.数组的解构赋值。
let arr = ['zhangsna', 'lisi', 'wangwu'];
let [a, b, c] = arr;
console.log(a, b, c); //zhangsna lisi wangwu
let [a, b, [c, d, [e, f, g]]] = [1, 2, [3, 4, [5, 6, 7]]];
console.log(a, b, c, d, e, f, g); //1 2 3 4 5 6 7
let [a, b, c, d] = [1, 2, 3];
console.log(a, b, c, d); //1 2 3 undefined
let [a, b, c, d] = [1, 2, 3, 4, 5];
console.log(a, b, c, d); //1 2 3 4
//求最大值、最小值及数组长度
const fn = function(arr) {
arr.sort(function(a, b) {
return a - b;
});
return [arr[0], arr[arr.length - 1], arr.length];
}
let [min, max, len] = fn([12, 3, 455, 67, 8, 9, 1]);
console.log(min, max, len); //1 455 7
//2.对象的结构赋值;对象是无序的。
var obj = {
a: 1,
b: 2,
c: 3
};
var {
a,
b,
c
} = obj;
console.log(a, b, c); //1 2 3
//修改变量的名称
var {
name1: xingming, //得到值的是xingming,name1没有值
age,
sex
} = {
name1: 'zhangsan',
age: 100,
sex: '男'
};
console.log(xingming, age, sex); //zhangsan 100 男
var obj = {
name: 'zhangsan',
age: 100,
sex: '男'
};
var {
age
} = obj;
console.log(age); //100
扩展运算符
扩展运算符用三个点号(...)表示,功能是把数组或类数组对象展开成一系列用逗号隔开的值
对于扩展运算符,只需要记住一句话:
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
//1.求最大值
var arr = [12, 3, 4, 567, 1, 36];
console.log(Math.max(...arr)); //max参数用逗号隔开的单个的值 567
console.log(arr); //(6) [12, 3, 4, 567, 1, 36]
console.log(...arr); //12 3 4 567 1 36
//2.数组的合并
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr3 = [7, 8, 9];
console.log([...arr1, ...arr2, ...arr3]);//[1, 2, 3, 4, 5, 6, 7, 8, 9]
//3.引用传递
let arr1 = [1, 2, 3];
let arr2 = arr1;
arr2.push(4);
console.log(arr1);//[1, 2, 3, 4]
console.log(arr2);//[1, 2, 3, 4]
let arr1 = [1, 2, 3];
let arr2 = [...arr1];
arr2.push(4);
console.log(arr1); //[1, 2, 3]
console.log(arr2); //[1, 2, 3, 4]
//4.类数组转换成真正的数组。
<ul>
<li>111111</li>
<li>111111</li>
<li>111111</li>
<li>111111</li>
</ul>
aLi = [...aLi];
aLi.push(document.body);
console.log(aLi); // [li, li, li, li, body]