当前位置: 首页 > 科技观察

JavaScript知识点整理

时间:2023-03-12 13:59:18 科技观察

JavaScript是根据ECMAScript标准设计和实现的。后面提到的JavaScript语法其实就是ES5标准的实现。先说说基本语法吧?最基本的语法是什么?所有语言的基本语法几乎都是一样的,无非就是数据类型、运算符、控制语句、函数等等,下面就罗列一下。5种基本数据类型&1种复杂数据类型JavaScript包含5种基本数据类型,分别是undefined/null/boolean/number/string。这就是五种基本数据类型,没有别的了!JavaScript包含1种复杂数据类型数据类型是Object类型,Object类型是所有其他对象的基类。注意:JavaScript不区分浮点数和整数,它们都是用数字表示的。上面说的5种基本数据类型,还有这里的1种复杂数据类型,这就是所有的数据类型!基本操作符都是常识,知道怎么回事就可以了。常用的运算符包括:算术运算符、关系运算符、布尔运算符、赋值运算符等。控制语句也就是我们常说的if-else等控制语句。常用的不多:if语句、switch语句、for语句、while语句、for-in语句。函数函数是对一小段逻辑的封装。理论上,逻辑越独立越好。JavaScript函数与其他语言有很大不同。JavaScript函数既可以用作参数,也可以用作返回值。此外,JavaScript函数可以接受任意数量的参数,并且可以通过arguments对象访问这些参数。任何语言的基本语法都是一样的,除了一些细节上的差异,大致就是上面这些:数据类型、运算符、控制语句、函数、模块等等。接下来介绍一些比较复杂的概念。变量、范围和内存问题变量JavaScript变量分为两种类型:基本类型和引用类型。其中,基本类型就是上面提到的五种基本数据类型,引用类型就是上面提到的Object以及其他基于它的复杂数据类型。基本型:实际占用内存空间大小。赋值时,会在内存中创建一个新的副本。存储在栈内存中。引用类型:指向对象而不是对象本身的指针。赋值时,只会创建一个指向该对象的新指针。存储在堆内存中。一句话,变量内存分配是指基本类型是内存中的实际值;而引用类型是内存中的一个指针,指向一个对象,多个引用类型可能同时指向同一个对象。那么,如何判断一个变量是哪种数据类型呢?要确定变量是哪种基本类型,请使用typeof运算符。要确定变量是哪种引用类型,请使用instanceof运算符。别忘了这个!范围变量在特定范围内声明,这决定了这些变量的生命周期以及哪些代码可以访问它们。JavaScript作用域只包括全局作用域和函数作用域,不包括块级作用域!范围可以嵌套以形成范围链。由于作用域链的存在,可以向上查找变量,即子函数可以访问父函数的作用域=>祖先函数的作用域=>直到全局作用域。这种函数也称为闭包。稍后正文会介绍。如下图所示,可以向上追溯每个作用域和嵌套作用域可以访问的变量。作用域链作用域的概念看起来很简单,但是在实际使用中会遇到很多问题。遇到问题一定要认真分析。内存问题JavaScript引擎有自动垃圾回收机制,所以你不需要过多关注内存分配和垃圾回收问题。这里就不展开了!引用类型前面提到,Object是唯一的复杂数据类型,引用类型都是从Object类型继承而来的。Array:数组类型Date:日期类型RegExp:正则表达式类型,多学点好!等等……那么问题来了,我们用的最多的函数的数据类型是什么?答案是函数类型!咦,我好像发现了什么?因为Function是引用类型,而JavaScript可以为引用类型添加属性和方法。嗯,功能也可以!这就是JavaScript函数强大而复杂的地方。也就是说:函数也可以有自定义的方法和属性!另外,JavaScript还封装了上面提到的五种基本类型中的三种,分别是Boolean、Number、String,不过用得不多,了解一下就可以了。顺便说一句,在所有代码执行之前,scope有两个内置对象,分别是Global和Math。其中,浏览器的Global就是window!至此,JavaScript中的基本概念已经介绍的差不多了,其中函数和作用域比较复杂,其他比较简单。接下来介绍JavaScript中一些稍微复杂一点的概念:面向对象。面向对象编程JavaScript本身没有类和接口的概念,面向对象编程是基于原型的。为了简单起见,我们只分析两个面向对象的问题:如何定义一个类?类继承如何实现定义一个类不说别的,直接告诉你。我们使用构造函数+原型来定义一个类。使用构造函数创建自定义类型,然后使用new操作符创建类的实例,但是构造函数上的方法和属性存在于每个实例上,不能共享,所以我们引入原型来实现方法的共享和属性。Prototype***,我们在原型上定义需要共享的方法和属性,将实例特有的方法和属性放到构造函数中。至此,我们通过构造函数+原型定义了一个类。实现继承我们之前讲过如何定义一个类,所以我们定义一个父类和一个子类。如何让子类继承父类?别的不说,直接告诉你。JavaScript通过原型链实现继承!如何构建原型链?只需将子类实例赋值给父类构造函数的原型即可。这很容易,但你必须记住它!继承原型链并构建原型链后,子类就可以访问父类的所有属性和方法了!面向对象的知识可以写成一本书,这里只是简单介绍最基本和常用的概念。函数表达式在JavaScript中有两种定义函数的方法:函数声明和函数表达式。使用函数表达式不需要给函数命名,从而实现动态规划,即匿名函数。有了匿名函数,JavaScript函数就有了更强大的用途。Recursion递归是一种很常见的算法,经典的例子就是斐波那契数列。不说别的,只说递归的最佳实践,把代码上传:递归就是这样,很多人还在用arguments.callee方式,改回函数表达式方式,这是最佳实践。啰嗦一句,很多人觉得递归不好写,其实如果分成两步,就会清楚很多。边界条件,通常是if-else。递归调用。按照这个模式,找几个经典的递归练练手,就会熟练了。闭包很多人常常认为闭包很复杂,容易掉坑,其实不然。那么什么是闭包呢?如果一个函数可以访问另一个函数范围内的变量,那么它就是一个闭包。由于JavaScript函数可以返回函数,自然地,创建闭包的一种常见方法是在另一个函数中创建一个函数!这没什么神奇的,在父函数中定义子函数就可以创建闭包,子函数可以访问父函数的作用域。我们通常被闭包吓到是因为我们被闭包困住了,尤其是面试题中的一堆闭包。前面提到了闭包的定义,也提到了如何创建闭包,那我们就来说说闭包的缺陷以及如何解决?/*我们通过subFuncs返回函数数组,然后分别调用执行*///返回函数数组subFuncs,而这些函数都有对superFuncs变量的引用//这是一个典型的闭包//那是什么问题是?//当我们回过头来执行subFuncs中的函数时,得到的i其实一直都是10,为什么?//因为我们返回subFuncs时,superFunc中的i=10//所以当subFuncs中的函数执行完,输出i为10////以上就是闭包***的坑。一句话就是://子函数对父函数变量的引用是父函数运行完后变量的状态functionsuperFunc(){varsubFuncs=newArray();for(vari=0;i<10;i++){subFuncs[i]=function(){returni;};}returnsubFuncs;}//那么,如何解决上诉的闭包坑?//原理其实很简单,因为闭包坑的本质是:子函数对父函数变量的引用是父函数运行结束后变量的状态//那么我们解决这个问题的方法是:子函数对父函数变量的引用父函数的变量,使用运行时的状态//怎么做?//在函数表达式的基础上,增加自执行。functionsuperFunc(){varsubFuncs=newArray();for(vari=0;i<10;i++){subFuncs[i]=function(num){returnfunction(){returnnum;};}(i);}returnsubFuncs;}综上所述,闭包本身并不是一个复杂的机制,即子函数可以访问父函数的作用域。由于JavaScript函数的特殊性,我们可以返回函数。如果我们将函数作为闭包返回,那么函数引用的父函数变量就是父函数运行结束后的状态,而不是运行时状态。这就是关闭***的坑。为了解决这个坑,我们常见的做法是让函数表达式自己执行。此外,由于闭包引用祖先函数的范围,滥用闭包可能会产生内存问题。好像闭包没什么用,那么闭包有什么用呢?主要是封装...封装闭包可以封装私有变量或者块级作用域。封装块级作用域JavaScript没有块级作用域的概念,只有全局作用域和函数作用域,所以如果我们要创建块级作用域,可以通过闭包来模拟。创建并立即调用一个函数封装了一个块作用域。这个函数可以立即执行里面的代码,执行完内部变量会立即销毁。封装私有变量JavaScript也没有私有变量的概念。我们还可以使用闭包来实现公共方法,通过隐藏变量来封装私有变量来暴露方法。我能总结一下吗?这几乎是JavaScript的一些基本语法和稍微高级的用法。其实,所谓高级,就是JavaScript“不成熟”的表现,尤其是面向对象,出于工程需要但JavaScript本身并没有绝对支持。好在ES6***标准解决了很多问题,你在使用Babel的时候不需要过多考虑兼容性问题。如果你是新手,建议你直接上ES6+Babel。JavaScript的基础主要包括:5种基本数据类型、1种复杂数据类型、运算符、控制语句、函数等。了解基本语法后,还需要学习JavaScript的变量、作用域、作用域链。检查时可以使用通用引用类型。作为体验过的人,建议多学习一些规则,对自己的代码水平会有很大的提升。面向对象编程部分有很多方法,你只需要记住使用构造函数+原型定义一个类,使用原型链实现继承即可。有关更多扩展,请转到本书。函数表达式导致了几个有趣的事情:递归、闭包和封装。记住递归的最佳实践,闭包的定义和缺陷,闭包的适用场景。JavaScript作为一门动态语言,与其他语言有着很大的不同,这也导致了很多人学习JavaScript的难度。但是如果你现在再看之前的文章,虽然是一个简短的总结,但这是JavaScript的主要内容,所以不要被自己吓到。还有一点,如果你是新手,我建议你直接上ES6+Babel。