JS

1.JS基本语法

1.1 变量

1.1.1 JS语句

弹框警示:alert(“警告”);
提示:prompt(“请输入年龄”,“18”);
控制台打印输出:console.log("");

1.1.2定义变量

  1. 使用var关键字定义变量 var a定义变量默认为undefined类型
  2. `var a = 1 , b = 2 , c = a + b;
  3. 检测数据类型:
    typeof(NaN); typeof(Infinity); typeof(Null);
    结果:number number object
    null中存放空对象指针也是一个对象

1.1.3 类型检测

  1. typeof (常用) 检测的数组和null都是Object类型console.log(typeof(null)) //object
  2. instanceof 判断是否某种类型,任意类型都是Object的子类 console.log([] instanceof Array) //true
  3. Object.constructor 原型会被覆盖导致不准确。undefined和null没有constructor属性,使用会报错 const num = 1 console.log(num.constructor === Number); // true
  4. Object.prototype.toString.call() console.log(Object.prototype.toString.call([1,2])) //[object Array]

1.1.4 类型转换

  1. 数据类型转换:.toString() (undefined 和null 用String()方法)
console.log(true.toString());
console.log(String(undefined))

+号两边都是数字为运算,有一边为字符串则拼接为字符串
console.log(true + "")
2. 数值类型
Number()方法;适用任何数据类型

  • 纯数字字符串转为对应数字,空字符串和空白字符串转为0,非空非纯数字字符串转为NaN
  • 布尔值:true转为1 false转为0
  • null转为0
console.log(" ")//0
console.log("undefined")//NaN
console.log("null")//0
console.log("a")//NaN
console.log("123")//123
  • parse()方法:
    作用:浮点数取整; 字符串转为整数数字(不是数字开头字符串转为NaN)
  • parseFloat()方法:
    作用:转为浮点数;
  • 应用:
   console.log(num);
  • Boolean()方法
    NaN、0、“”、 空字符串、null、undefined转为false
    其余转为true
  1. 运算
  • 逻辑运算:
    a&&b a为真则为b
    a||b a为真则为a
    恒等于
  • 比较运算:
    隐式转换:“123”-123; true-1 ;flase-0; null-0
    undefined-NaN;""-0;“abc”-NaN
    null>=(或<=)0 //true
    null==0 //flase
    undefined == null //true
    NaN != NaN //true
    Infinity == Infinity //true
    Infinity === Infinity //true
    “abb” < “baa” //true 只比较第一个字符的ascll码
    6 < “12” //true 12转数字和6比较
    “6” > “12” //true 比较6和1 的ascll码
  • 算术运算(返回一个布尔值)
    ==只判断值大小是否相等,不判断数据类型
    === 判断数据类型是否相等
  1. 流程控制语句
    break 适用于while for dowhile 语句
    break 可以中断循环本层循环,也可中断外层循环;
   waiceng:for(i=0;i>10;i++){
      for(j=0; j>8, j++){
            console.log(i,j);
            if (j>=2){
               break waiceng ;
            }
      }
   }

2函数

浏览器在调用函数的时候会开辟新的空间执行函数内容。局部变量退出作用域时会销毁。全局变量在关闭浏览器时销毁。

  • 作用域:函数首先会调用自己内部变量,未找到时会调用全局变量。产生遮蔽效应。定义变量时不加var关键字则定义全局变量
  1. return:将返回值作为函数的结果。没有return则为undefinde
sum(a,b) {
   return a+b
}
  1. arguments对象
    argument对象中存储传递的所有实参,是一个伪数组,可以遍历。函数实参和形参个数不一致,所有实参都会存储在函数内部的arguments数组对象中。可以利用argumens中数组长度实现java中的重载。

  2. 预解析:执行代码时分为预解析和代码执行过程。
    1.把变量声明提升到当前作用域的最前面,只提升声明不赋值
    2.把函数声明提升到当前作用域的最前面,只提升声明不调用
    3.先提升var的创建和初始化赋值不会被提升,let的创建被提升,初始化和赋值不会被提升,函数的创建\初始化\赋值都会被提升
    4.函数表达式进行的是变量声明提升。提升后变量内部存的是undefined。
    5.IIFE自调用函数。定义时就立即使用。通过添加±()!实现矮化成表达式后面加()可以立即执行

   var foo=function () {
      console.log(2);
   }();//函数表达式方式可以在定义时被立即执行
   function fun(){
      console.log(1);
   }();
   或 (function fun(){
      console.log(1);
   }();
   //常用:
   (function (a){
         console.log(a);
   })(4);
  1. 异常
    throw new Error(“抛出异常提示”);

高阶函数

屏蔽实现细节,抽象通用问题

函数作为参数

function fliter(arr,fn){
	let result = []
	for(let i=0 ;i<arr.length;i++){
		if(fn(arr[i])){
			result.push(arr[i])
		}
	}
}
let array = [1,2,3,5,6]
let r = fliter(array,function(item){
	return item%2 === 0
})
console.log(r)// 2,6

函数作为返回值

function once(fn){
	let done = false
	return function(){
		if(!done){
		  done = true
		  return fn.apply(this,arguments)
		}
	}
}
let pay = once(function(money){
	console.log(`支付${money}RMB`)
})
pay(6)
pay(6)
//调用两次函数只执行一次

作用域链

function bar() {
    console.log(myName)
}
function foo() {
    var myName = "极客邦"
    bar()
}
var myName = "极客时间"
foo()  //输出结果为极客时间

作用域链
在每个执行上下文的变量环境中都有一个outer指向外部执行上下文。如果代码使用到一个变量,js引擎会在当前执行上下文中寻找,如果没有就在outer指向的执行上下文中查找. bar()函数的outer指向(作用域链指向)是由词法作用域决定的。foo和bar的上级作用域都是全局作用域,词法作用域在编译阶段就决定好了,与函数调用无关

4.1词法作用域

概念:是由代码中函数声明的位置来决定,是静态的作用域,通过它能够预测代码在执行过程中如何查找标识符
词法作用域链
词法作用域由代码中函数声明的位置决定,在编译阶段已经确定,与函数调用无关。

块级作用域中的变量查询

function bar() {
    var myName = "极客世界"
    let test1 = 100
    if (1) {
        let myName = "Chrome浏览器"
        console.log(test)
    }
}
function foo() {
    var myName = "极客邦"
    let test = 2
    {
        let test = 3
        bar()
    }
}
var myName = "极客时间"
let myAge = 10
let test = 1
foo()

块级作用域中的查找过程

5.闭包

函数定义时能记住自己生成的作用域环境和函数自己。
定义:根据词法作用域的规则,内部函数总是可以访问外部函数声明的变量,当通过通过一个外部函数返回一个内部函数后,即使该外部函数已经执行结束,内部函数引用外部函数都买的依然保存在内存中,这些变量的集合称为闭包
用途:1.可以在函数外部读取函数内部成员 2. 让函数内成员始终存活在内存中
使用自调用函数解决闭包作用域限制的问题

function foo() {
    var myName = "极客时间"
    let test1 = 1
    const test2 = 2
    var innerBar = {
        getName:function(){
            console.log(test1)
            return myName   },
        setName:function(newName){ myName = newName        }
    }
    return innerBar
}
var bar = foo()
bar.setName("极客邦")
bar.getName()
console.log(bar.getName())

执行到foo函数内部的return innerBar的时候
执行到return bar时候的调用栈
内部函数getName和setName总是可以访问他们外部函数
foo中的变量,所以当iinnerBar对象返回给全局变量bar时,虽然foo函数执行结束,但是getName和setName依然可以使用函数中的变量myName和test1的
闭包产生的过程
foo函数执行完成以后它执行的上下文从栈中弹出,由于函数方法中使用了foo函数内部变量所以这两个变量依然保存在内存中。
当函数变量被调用时,沿着当前执行上下文——》foo函数闭包——》全局执行上下文的顺序查找变量。
调用bar时的栈状态

闭包回收

如果闭包函数是一个全局变量,闭包会一直存在知道页面关闭;如果闭包以后不再使用,就会造成内存泄漏
如果引用闭包的函数是个局部变量,等函数销毁后,在下次 JavaScript 引擎执行垃圾回收时,判断闭包这块内容如果已经不再被使用了,那么 JavaScript 引擎的垃圾回收器就会回收这块内存。
所以在使用闭包的时候,你要尽量注意一个原则:如果该闭包会一直使用,那么它可以作为全局变量而存在;但如果使用频率不高,而且占用内存又比较大的话,那就尽量让它成为一个局部变量。

3.对象

学习文档:MDN

  1. 创建对象:
  • 方法一:通过字面量创建对象
var person = {
   name : "zs",
   age : "19",
   sayHi : function {
      console.log("nihao");
   }
}
  • 方法二:使用new Object创建
var person1 =new Object();
//添加属性方法
person1.name = "ZS";
person1.sayHi = function () {
   console.log("hellow");
};

   new 在内存中创建了新的空对象;让this指向新的对象;执行构造函数为新对象加属性和方法;new会返回这个新对象。new一个构造函数就会创建一个新对象

  • 方法三:使用工厂方法创建对象
function createPerson(name,age) {
      //创建一个空对象
      var person = new Object();
      //添加属性和方法
      person.name = name;
      person.age = age;
      person.sayHi = function (){
         console.log("hello");
      };
      //将对象作为函数返回值
      return person;
}
      //想创建对象可以调用工厂函数
      var p1 = createPerson("zs","18");
      console.log(p1);
  • 方法四:自定义构造函数
function Person(name,age){// 构造函数首字母大写
      //不需要使用 new 一个新对象,用this替代将来创建的新对象
      this.name = name;
      this.age = age;
      this.sayHi = function () {
         console.log("hello");
      };
      //new 创建新对象会自动生产返回值。不需要添加return
      var p1 = new Person("zs",18);
      console.log(p1);
}
  1. 调用:
  • 方法一
   console.log(person.name);
   person.satHi();
  • 方法二
   console.log(person["name"]); 
   person["sayHi"]();

对象内部调用时用this关键字
delete person.name;//删除属性
person.age=10;//修改或新增属性

  1. 对象遍历
    for in 循环
for(var k in person){
   console.log(k+"项的属性值为"+person[k]);
}
  1. 内置对象
  • Math对象
    Math.pi 圆周率
    Math.random() 生产随机数
    Math.floor()/Math.ceil() 向下/上取整
    Math.abs() 绝对值
    Math.max()/Math.min() 最大/小值
    Math.sin()/Math.cos() 正弦函数
    Math.power/Math.sqrt() 指数幂/平方根
  1. 创建数组对象的两种方式
  • 字面量方式
    var arr = [1,2,3];
  • new Array() 构造函数方法
 var arr1 = new Array();//空数组
 var arr2 = new Array(1,2,3) //可以传参
 var arr3 = new Array("zs","li","ww");//字符串数组
 console.log(arr instanceof Array) //true;
 console.log(arr1 instanceof Array) //true;
  1. 数组对象数组属性和方法
  • Array 对象
    instanceof 检测某个实例是否时某个对象类型
    toString() 把数组转化成字符串,逗号分隔每项
    push() 数组末尾添加元素,并返回操作后长度
    pop() 删除数组最后一项,返回删除项
    shift() 删除数组第一项,返回删除项
    unshift() 在数组开头添加一个或多个元素,返回操作后长度

  • concat() 两个数组合并成为一个新的数组,原数组不受影响

  var arr = [1,2,3] , ar = [4,4];
  var arr1 = arr.concat([5,4,3]);
  var arr2 = arr.concat(ar);
  console.log(arr);//[1,2,3]
  console.log(arr1);//[1,2,3,5,4,3]
  console.log(arr2);//[1,2,3,4,4]
  • slice(start,end) 从当前数组中截取一个新的数组,不影响原来数组,返回一个新数组,从start到end(不含)的元素;参数为正表示下标,为负表示从后往前数几个。不传值时表示浅拷贝一份
   var arr = [1,2,3,4,5,6];
   var arr1 = arr.slice(2,4); //[3,4]
   var arr2 = arr.slice(-4,-1); //[3,4,5]
   var arr3 = arr.slice(-1,-4); //[]
   var arr2 = arr.slice(-4) //[3,4,5,6] 一直截取到结束
  • splice(index,howmany, element1···) 删除、插入、替换
    index: 删除元素开始位置
    howmany: 删除元素个数,可以是0
    elememt1 :要替换的新数据;
   var arr = [1,2,3,4,5,6,7,8];
   arr.splice(2,5);     //删除
   console.log(arr.splice(2,5));//[3,4,5,6,7]返回删除的数组
   console.log(arr); //[1,2,8] 从下标2开始删5个
   var arr1 = [1,2,3,4,5,6,7,8];
   arr1.splice(2,5,"h1","h2"); //替换
   console.log(arr);//[1,2,3,h1,h2];
   var arr2 = [1,2,3,4,5,6,7,8];
   arr2.splice(3,0,"h1","h2"); //增加
   console.log(arr2);//[1,2,3,h1,h2,4,5,6,7,8]
  • indexOf() 查找数组中首次出现元素的下标
var arr = [1,2,3,4,5,6,7,4,5];
console.log(arr.indexOf(4)); // 3  
console.log(arr.lastIndexOf(4)); // 7
console.log(arr.index(8)); //-1
  • reverse() 数组完全颠倒 返回值为倒叙后值
    arr.reverse();

  • sotr() 默认根据字符编码顺序,从大到小

   var arr = [1,2,3,4,5,10,20];
   arr.sort(function(a,b){    //实现正序
      if(a < b ) {
            return -1;  //表示a 排在 b 前面
      }else if (a > b>) {
            return 1;   //表示 a排在 b后面
      }else {
            return 0;   //a 和 b不变
      }
   });
   console.log(arr);
  • join() 通过参数作为连字符将数组的每项用连字符连城完整的字符串
   var str = arr.join();
   console.log(str); //1,2,3,4,5,6
   var str1 = arr.join(*);
   console.log(str1); //1*2*3*4*5*6
  1. 基本包装类型:基本类型数据进行特殊操作时,会暂时包装成对象,结束后销毁。
 var str1 = "abcde" ;
 var str2 = new String("abcdef") ;
 
  1. 字符串特点
    字符串不可修改,更改字符串内容只是整改存放字符串内容的地址。字符串的所有方法,都不可修改字符串本身。
  • str.length
  • str.charAt() 返回指定位置的字符,从0 开始
  • str.indexOf() 返回指定的字符串中第一个出现位置的下标
  • str.concat() 连接两个或多个字符串,生成新串,原串不变
    var str2 = str.concat("hahaha","h2")
  • str.split() 把一个字符串分割成字符串数组
    var arr = str.split("");
  • toLowCase()/toUpperCase() 字符串转小写/大写
  • slice(start, end) 提取字符串某个部分,返回提取部分
  • substr(start,howmany) 抽取从start下标开始howmany长度的自字符
  • substring(start, end) 提取介于两个指定下标之间的字符,原串不变,返回提取值

[folktail官网][https://folktale.origamitower.com/]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值