JS进阶

一·作用域

局部作用域是在函数作用域内和函数内,局部声明的变量不能在函数外使用。全局作用域在函数外,函数内都能用。

作用域链,优先查找当前作用域,在冒泡一级一级往上查找。

垃圾回收机制:局部变量,未使用就会自动被回收;而全局变量一般不会被回收,关闭页面才会被回收。

标记清除法:从根部扫描对象,能查找到就使用,查找不到就回收。

闭包:内层函数+外层函数的变量

变量提升:var只提升当前作用域的最前面,只提升不赋值;函数也有变量提升,也可以先声明,在写函数。但是函数表达式必须先声明在调用比如说:

        fun() //错的
        var= function fun() {
            console.log(11); 错的
        }
        var fa //对的
         function fa() {
            console.log(11);
        }

二·函数参数

动态参数,arguments只存在与函数的内部,是一个伪数组传入的参数可以是任意的。

        function getsum() {
            let sum = 0
            for (let i = 0; i < arguments.length; i++) {
                sum += arguments[i]
            }
            console.log(sum);

        }
        getsum(1, 5, 8)

剩余参数:...other:是一个真数组。...前面是指的是除了a以外的数据元素,这里代码,并不包括1求和,当然这里也可以除多个数据

        function getsum(a, ...arr) {
            let sum = 0
            for (let i = 0; i < arr.length; i++) {
                sum += arr[i]
            }
            console.log(sum);

        }
        getsum(1, 5, 8)

展开运算符:

        const arr = [1, 5, 3]
        console.log(Math.max(...arr));

箭头函数


        const fun = () => {
            console.log(1);

        }
        fun()
        const fa = x => console.log(111);
        const f = x => {
            console.log(x + x);
            console.log(1);
        }
        const q = uname => ({ uname: uname })
        console.log('你好'); //可以返回一个对象,不需要return

箭头函数里面的this指向,只有函数里面才有this,对象里面的this,如果在函数里面,这里的this为window,如果是嵌套函数,this就指的是obj

三·解构赋值

将数组的单元值批量赋值给一系列变量

        const arr=[1,2,3]
        const[min,midd,max]=arr //min=arr[0] ,midd=arr[1],max=arr[2]

两数交换,记得加分号。[]有这个开头,前面的代码尾部要加分号;

        let a = 1
        let b = 2;
        [b, a] = [a, b]

数组解构:


        const [a, b, [c, d]] = [1, 2, [3, 4]]
        console.log(a); //1
        console.log(b); //2
        console.log(c); //3
        console.log(d); //4

        const [e, f, g] = [1, 2, [3, 4]]
        console.log(e); //1
        console.log(f); //2
        console.log(g); //[3,4]
        

对象的解构,这里相当于,const uname=user.name

        const user={
            name:'小明',
            age:11
        }
        const{uname,age}=user

        console.log(uname); //小明
        console.log(age); //11
        

对象解构变量改名 旧对象名:新对象名

forEach(ele,index):他不会返回数组,只是遍历,而map会返回数组

filter,筛选数组元素

        const arr = [10, 20, 30]
        const newarr = arr.filter(item => item >= 20)
        console.log(newarr);

四·对象与内置构造函数

利用new Object()构造函数;

自定义构造函数创建对象,快速创建类似对象,函数名首字母大写,并且用new来创建

    function Pig(name, age, gender) {
      this.name = name
      this.age = age
      this.gender = gender
    }
    const p = new Pig('佩奇', 11, '女')

实例对象和方法称为实例成员,实例对象相互独立。而静态成员是写在构造函数身上的,静态成员只能通过构造方法实现

四·内置构造函数

Object静态构造方法:

获得对象属性值,返回的是数组:

        const o = { name: 'lii', age: 12 }
        console.log(Object.keys(o));
返回{'name','age'}
 console.log(Object.values(o)); 返回{'lii',12}
const oo={}
Object.assign(oo, o) 将o拷贝给o

数组reduce累计方法,它可以将数组求和,可以有初始值也可以无初始值

        const arr = [1, 2, 4]

        const sum = arr.reduce((prev, current) => prev + current) //无初始值 7
 const sum = arr.reduce((prev, current) => prev + current,10) 有初始值17

Number的toFixed(n)可以保留几位小数,注意这里是四舍五入的。

五·面向对象

面向对象是把事物分解成一个个对象,然后由对象间份分工与合作。

对象的公共方法可以用prototype,这个是Object的一个属性,不同的对象调用这个创建的方法内存都是公用的。

        Star.prototype.sing=function(){
            console.log('唱歌');
        }

原型函数和构造函数里面的this都是指向实例对象。

再比如说用原型函数自定义函数求和


        Array.prototype.sum = function () {
            return this.reduce((prev, item) => prev + item, 0)
        }
        console.log([1, 2, 3].sum());

如果一个对象里有多个构造方法,我们可以给原型对象采取形式赋值的模式,但是这个时候要用constructor重新指回原型的构造函数,如下面这个代码所示

        function Star(uname, age) {
            this.uname = uname
            this.age = age
        }

        Star.prototype = {
            //重新指回创作这个原型的构造函数
            constructor: Star,
            sing: function () {
                console.log('唱歌');
            },
            dance: function () {
                console.log('跳舞');
            }
        }

原型的继承

继承的时候,原型函数指向父亲构造函数,但是这个时候constructor要指回它本身自己。


        function Person() {
            this.eays = 2,
                this.head = 1
        }

        function Woman() {
        }
        Woman.prototype = new Person()
        Woman.prototype.constructor = Woman
        const pink = new Woman()
        console.log(pink.head);

父亲用构造函数,这样子类原型new创建新的父类函数,在给子类创建新的方法,可以与不同子类的构造函数区分开来。

浅拷贝:一般只能拷贝对象里面非函数类的内容,有一下两种方法可以实现浅拷贝

        const Obj={
            uname:'pink',
            age:18,
            fiamy:{
                ba:'小王'
            }
        }

        const o={}
        Object.assign(o,Obj)  //方法一
        const o={...obj}   ///方法二

深度拷贝,一般要用到函数递归的方法,对象里面有数组和对象都需要用到,一般都是先判断是什么,在根据这个给新对象添加一个空数组或者空对象,接下来演示一下

        const Obj = {
            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球']
        }

        const o = {}
        function deepCopy(newObj, oldObj) {
            for (let k in oldObj) {
                if (oldObj[k] instanceof Array) {
                    newObj[k] = []
                    deepCopy(newObj[k], oldObj[k])

                }
                else if (oldObj[k] instanceof Object) {
                    newObj[k] = {}
                    deepCopy(newObj[k], oldObj[k])
                }
                else {
                    newObj[k] = oldObj[k]
                }
            }
        }

        deepCopy(o, Obj)

还有其他方法:lodash拷贝,运用js库可以实现;还可以用JSON的方法实现

        const Obj = {
            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球']
        }

        const o = JSON.parse(JSON.stringify(Obj))

六·异常处理

throw:异常抛出会中断程序

try ...catch,如果try尝试运行代码有错误,catch就会捕获错误信息,err.message可以写出错误信息。finaly,不管程序有没有错误都会执行finaly后面的代码

七·改变this

普通函数谁调用它,this就指向谁

dom.call()可以改变this的指向

        const Obj = {
            uname: 'pink',
            age: 18,
            hobby: ['乒乓球', '足球']
        }

        function fn(x,y){
            console.log(this); //原本是指向widow,使用call后指向Obj
            
            console.log(11);
            
        }
        fn.call(Obj,1,2)

call()不仅可以改变this 的指向,还能调用函数

apply(返回对象,数组)这个方法与call类似,但是传入的数据是数组,就可以用这个方法求函数最大值或者最小值等等

        const arr = [100, 22, 33]

        const max = Math.max.apply(Math, arr)

bind(this要指向的对象),返回的是一个函数,dom=dom.bind(),相当于拷贝了一个函数

防抖:单位时间内,频繁触发事件只执行最后一次

节流:单位时间内,频繁触发事件只执行第一次


JS进阶
http://localhost:8090//archives/jsjin-jie
作者
骆伟林
发布于
2024年10月21日
许可协议