ES5 js 中数组 底层 其实 都是 关联数组
找出出现次数最多的字符和出现的次数* ************
// js 中 底层 其实 是 关联数组
var str ="helloworld";
for(var i = 0 ,newArray = []; i<str.length ;i++){
// 数组中如果不存在 str[i]
if(newArray[str[i]] === undefined){
//强行赋值为 1
newArray[str[i]] = 1;
}else{//否则
newArray[str[i]]++;
}
}
var maxChar , count = 0;
//循环 newArray
for(var key in newArray ){
if(newArray[key]>count){
count = newArray[key];
maxChar = key;
}
}
console.log(maxChar,count) // l 3
ES5 严格模式
一 、 "use strict"的 要求
1. 禁止给 未声明的变量 赋值 -->报错
2. 普通函数 或者匿名函数自调用 中的this 不在指向window 而是 undefined
3. 静默失败升级为错误 (即使代码错误 也不报错 为 静默 失败)
4. 不推荐使用 arguments 和 arguments.callee 影响程序的执行效率
二、对 对象的保护
1.对象属性
数据属性 ----实际存储 属性值的属性
{
value:属性值,
writable:控制是否可以修改,/* true/false*/
enumerable:控制是否可以循环,/*true/false*/
configurable:1.控制是否可以删除, /*true/false*/
2..控制是否可以修改前两个属性
configurable 一旦设置了false 为不可逆 的
}
2. 访问器属性 (理解vue的MVVM模式重点知识) ----不实际存储属性值,提供对属性保护
get(){.....} //获取属性值
set(){......}//设置属性值
本质上是两个函数
Object.definedProperties()
3.对象 -----防篡改
ES6
1.模版字符串
由反引号 包裹 `` 并且 支持换行
${ *js表达式* }
// 为了更好 的字符串拼接
// 但是 不同的 是 模板字符串支持动态生成内容
// 变量 函数调用 如:fun() 算数运算
// 比较运算 三目运算 创建对象 和数组的访问
//---------------------------------------
var str = "hello world";
console.log(str)//hello world
// 变量
var newStr = `hello world`
console.log(`${newStr}`)//hello world
//函数调用 如:fun()
var fun = function (){
return `模板字符串`
};
console.log(`${fun()}`) //模板字符串
// 创建对象
var date = `${new Date().getTime()}`
console.log(date) //距元年的毫秒数
2.let var const
//ES3 . ES5
a . **var 关键字 会出现声明提前 (hoist)
声明变量为赋值 值 为 undefined**
**并且没有块级作用域**
//var 关键字 会出现声明提前 (hoist)
var a ;
console.log(a)//undefined
b . const 为常量 一旦声明 不能修改
//const 为常量 一旦声明 不能修改
const b = 100;
console.log(b)//1000
b=400;
//报错 Uncaught TypeError: Assignment to constant variable
//类型出错:赋值是不可改变
ES6
c . let
块级作用域 -----本质是 匿名函数的自调 (function(){.......})() 并且 修改变量 名避免冲突
1 在 同级作用域 不能 声明两个相同的变量名
2 前不允许提前使用该同名变量
3 不存在声明提前,不会污染全局 即 即使在window下使用声明变量
也不会保存在window中
// 即使在 在window 中 声明的变量 也会返回 undefined
let a = 100;
console.log(a)//100
window["a"]//undefined --->js 中数组 底层 其实 都是 关联数组
3.箭头函数 ------回调函数的简写
1. 箭头函数的特征:作用域 的 内外this 相同 2.在箭头函数中 不支持 arguments
只要不希望作用域 内外this 相同是 不能使用 箭头函数 比如:对象中的方法
let arr = [5,4,3,2,1]
// 将数组从小到大排序
arr.sort(function(){return a-b})// [1, 2, 3, 4, 5]
let newArr = [5,4,3,2,1];
//使用箭头函数 简写为
newArr .sort((a,b)=>{return a-b})// [1, 2, 3, 4, 5]
4.参数增强
a.默认参数
//默认参数
var fun = function (a,b,c = 1){
// 相当于 ES3 ES5
// c = c || 1;
console.log(c)
}
fun()//1
b.剩余参数 -----代替arguments 不确定的情况
...rest 语法 的优点 是 纯正的数组 可以使用 数组的API 如:concat fliter some slice splice.....
注意:箭头函数 指只支持 rest 语法
//ES3 ES5 列如求和运算:
var fun = function (a,b,c,d){
//Arguments 类数组对象 指的是函数调用时传入的实参列表 只能在函数体内使用 arguments
//将类数组对象转化为数组的方法 :[].slice.call(arguments)
//获取部分数组对象 转化为数组 :[].slice.call(arguments,i)
for(var i = 0,sum = 0; i<arguments.length;i++){
sum += arguments[i];
}
return sum;
}
fun(1,2,3,4,5)//15
//ES6
let newFun = function(a,b,c,...arr){
// ...rest 语法 会收集函数调用时除a,b,c之外的 传入的实参值
let sum = 0;
for(let i = 0;i<arr.length;i++){
sum += arr[i];
}
return a + b + sum;
}
newFun(1,2,3,4,5,6,7)
c. 打散数组 ----代替apply 打散数组 ,将值单个传入 函数中
apply 本质就是替换this 顺便打散数组,将值单个传入
{ call bind apply 都是替换this 只是 用的时机不同而已 }
详见 多维数组降维 建议 手写
强调 :
在函数 调用时 会将数组打散
在函数定义时 会将传入的参数 收集 起来 放在数组中 为 纯正的数组
//ES6
let sum = function (a,b,c,d){
return a + b + c + d
}
sum(...[1,2,3,4])//10
5.解构 数组解构 对象解构
// 数组解构 对象解构 相同
let [a,b] = [3,5];
/*
常用于 两变量之间的交换值
[a,b] = [b,a];
*/
console.log(a,b)
6 .**class********
//ES3 ES5 OOP 面向对象
//Animal的构造函数 一个类型 包含 属性 和 方法
function Animal(name,age){
this.name = name;
this.age = age;
}
Animal.prototype.say = function(){
return "my name is " + this.name + " age "+this.age
}
//People的构造函数
function People(name,age,className){
//将this替换为Animal中的this ; 将来 创建 子对象时 new 指向的是 People中的this
Animal.call(this,name,age);
this.className = className
}
People.prototype.self = function (){
return this.name + " "+ this.age +" "+ this.className;
}
//设置 People类型 继承 Animal类型 ---->两个类型之间的继承
Object.setPrototypeOf(Pepole.prototype,Animal.prototype);
var People = new People("lilei",21,"初一");
people.say(); //"my name is lilei age 21"
people.self(); //"lilei21初一"
//ES6 实现两类型之间的继承
class Animal{
constructor(name,age){
this.name = name ;
this.age = age;
}
// Animal.prototype.say = function (){.......}
// 可以省略 Animal.prototype 简写为: say = function(){....};
// 也可以省略 = function 而 = function只是单纯的语法糖而已 可 直接简写为 say(){....}
// 也就是说 在 class 中 定义的方法 是定义在构造函数的原型对象中
say(){
return "my name is " + this.name + " age "+this.age ;
}
}
class People extends Animal{
constructor(name,age,className){
//ES6 ---> super(name,age) 代替 Animal.call(this,name,age);
super(name,age);
this.className = className;
}
// People.prototype.say = function (){.......}
// 可以省略 people.prototype 简写为: self= function(){....};
// 也可以省略 = function 而 = function只是单纯的语法糖而已 可 直接简写为 self(){....}
self(){
return this.name + " "+ this.age +" "+ this.className;
}
}
let people = new People("Lei Jun",45,"高三(三班)")
people.say() // "my name is Lei Jun age 45"
people.self() //"Lei Jun 45 高三(三班)"
7.Promise异步对象 ----避免回调地狱---> 什么 是回调地狱 回调函数的多层嵌套
Promise.all([
function fun1(){/**/},
function fun2(){/**/},
function fun3(){/**/},
]).then(result=>{console.log(result)}) // .tnen(result=>{console.log(result)}) 像是钩子一样
new Promise(function(resolved,rejected){/*........*/})
在 Promise主体 中 没有return 只有 resolved 相当于 函数中的 return
resolved 成功回调函数为 then(result=>{/* ......*/ })
rejected 会自动调用 失败回调函数 catch(err=>{/* ......*/})
一个 Promise有以下几种状态:
pending: 初始状态,既不是成功,也不是失败状态。
resolved: 意味着操作成功完成。
rejected: 意味着操作失败。
8.Set对象
/new Set([iterable]);
// 如果传递的参数是 一个可迭代的对象 它的所有元素将不重复的被添加到Set对象中 ,
//如果不指定此参数 或者 传入的值为 null ,则新Set为空 size为0 即 【**Set集合中的值是唯一的**】
var arr = [1,2,3,4,5,6,6,7];
//利用数组的解构
//1.将 new Set() 返回的 集合 ---> 对象
//2.将对象打散 放进数组中
/*
new Set(arr) ---> 返回的 集合为 :{1, 2, 3, 4, 5, 6,7}
*/
console.log([...new Set(arr)])//[1, 2, 3, 4, 5, 6, 7]