文章目录
1.JavaScript的概述
JavaScript是脚本语言,边读取,边编译,边执行,可以一行一行的去运行
举个栗子:电影脚本:目的就是拍出电影的效果,需要编剧提前去写好剧本,指挥演员怎么去演。而我们的JavaScript的脚本:目的就是实现网页的效果,我们程序员就是导演,用编辑器写好脚本,指挥某些元素怎么操作。
注意事项:脚本语言—如果出现了脚本运行时的代码错误,那么错误代码后面的代码就不执行。(所以JS比CSS要严格很多)
2.JavaScript的组成
ECMAScipt(核心):JavaScript的语言基础
DOM(Document Object Model 文档对象模型):规定了访问HTML和XML的接口,即是浏览器提供给我们操作文档的一些功能,比如让网页当中的按钮变色
BOM(Browser Object Model 浏览对象模型):提供了浏览器窗口之间进行交互的对象和方法,即是操作浏览器的一些功能,如让浏览器刷新等功能
3.JavaScript的基本数据类型和复杂数据类型
基本数据类型:(6个)string 、number 、boolean、undefined、null、symbol(es6新增,表示独一无二的值)
复杂数据类型:object
4.JavaScript是弱数据类型的语言
弱数据类型的特点:变量可以存放任何数据类型的数据,并且在运算的时候,数据会自动地进行隐式转换
,Js所有的数据类型都可以通过var定义变量
var 变量名=数据
强数据类型特点:以C语言为例,定义不同的数据类型需要不同的关键词
例如float x=3.6; int y=4;
特殊中的特殊
5.JavaScript中的作用域与变量声明提升?
JavaScript的作用域
- 在Java,c等语言当中,作用域为for语句、if语句或{}内的一块区域,成为作用域
- 而在JavaScript中,作用域为
function(){}
的区域,称为函数作用域,JS主要通过函数划分作用域 - JS中的作用域又分为
局部作用域
和全局作用域
- 全局作用域:在script顶级写的变量和函数都是全局的,在外部文件顶级位置属性的变量和函数也是全局的。
<script>
var num=80 /*这是全局作用域*/
alert('num在外面输出的为'+num) /*调用了全局作用域的num 值为80*/
function func(){
alert('num在里面输出的为'+num)
}
func()
</script>
- 局部作用域:函数内部是独立的作用域
<script>
var num=80
alert('num在外面输出的为'+num)
function func(){
var num =100 /*这是局部作用域*/
alert('num在里面输出的为'+num) /*调用了局部作用域的num 值为100*/
}
func()
</script>
JavaScript的变量声明提升
JS中有变量声明这一个机制,当js在执行的时候,会分为两个阶段,一个是预解析,一个是执行,js预解析的时候会将所有用var声明的变量以及关键字的函数声明提升到当前作用域的最顶端,而赋值的语句在原地等待执行,预解析之后,再从上往下地逐行解析代码。
- 平时我们写的
var num=100
;虽然代码只有1行,但是js会分成2个部分进行读取
//声明变量,并提升到作用域的最前面
var num;
//在原位进行赋值
num=100;
- 我们写的代码,以为是从上往下执行的
var num =100
function func(){
console.log("第一次输出",num) //第一次输出 undefined
var num=200
console.log("第二次输出",num) //第二次输出 200
}
func()
- 其实js真正的运行状态如下所示
- 先把var 和function 声明预解析给提前了,再执行,而不是按照书写顺序从上往下执行
var num;
function func(){
var num;
console.log("第一次输出",num) //第一次输出 undefined
num=200
console.log("第二次输出",num) //第二次输出 200
}
num=100;
func();
注意:
- 在JavaScript中,函数声明与变量声明经常被JavaScript引擎隐式地提升到当前作用域的顶部
- 声明语句中的赋值部分并不会被提升,只有名称被提升了
- 预解析的过程调试代码的时候断点并不会经过,因为断点调试的时候,预解析的代码已经运行完毕了
- 函数声明的优先级会高于变量,如果变量名与函数名相同且未被赋值,则函数的声明会覆盖变量的声明
- 如果函数有多个同名的参数,那么最后一个参数(即使没有定义)也会覆盖前面的同名参数
6.介绍 JavaScript 的原型,原型链?有什么特点?以及闭包的相关知识
JavaScript 的原型
:每个函数都有prototype属性,这个属性值就是原型
JavaScript 的原型链
,任何的对象都是有__proto__属性,指向他的原型对象,原型对象也是对象,也有自身的__proto__属性,指向他的原型对象,也就是原型对象的原型对象,这样子形成的链式结构叫做原型链。
原型链是JavaScript实现继承的重要方式,原型链的形成是真正是靠__proto__ 而非prototype。
闭包
简单来讲,其实就是两个函数的互相嵌套,内部函数需要访问外部函数的变量。在这种条件下才可以形成一个闭包。
7.JavaScript如何实现继承?
- 构造函数的绑定:使用
call
和apply
方法,将父对象的构造函数绑定在子对象上面
function Animal(){
this.species=animal
}
function Dog(name,color){
Animal.apply(this,arguments);
this.name=name;
this.color=color
}
- 实例的继承:将子对象的prototype指向父对象的一个实例
Dog.prototype=new Animal()
8.数组去重的方法
var arr = [1, 2, 3, 7, 8, "a", "c", "f", "i", "a", "i", 1, 2]
- 通过数组的双重循环去重(以及splice方法)
数据量小的话是可以的,但是数据量大的话,效率不高
function removalRepeatArray() {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
// 如果有重复元素,将其删除
arr.splice(j, 1)
//由于少了一个元素,数组的下标需要往前退一个
j--
}
}
}
return arr
}
console.log(removalRepeatArray(arr));
- 通过数组的filter方法
filter方法
,是过滤掉重复的,然后重新返回给一个新的数组,所以我们需要设定一个进行接受,然后第一个参数是数组当中的某个元素,第二个参数是元素的位置,第三个表示的是数组本身
indexOf方法
如果数组当中存在这个元素,则返回的是第一次出现元素时候的位置,如果不存在,则返回负一
function removalRepeatArray() {
const newArr = arr.filter(function (element, index, self) {
return self.indexOf(element) === index
})
return newArr
}
console.log(removalRepeatArray(arr));
- 通过数组方法forEach+indexOf
function removalRepeatArray() {
const newArr = []
arr.forEach(function (item, index) {
if (arr.indexOf(item) == index) {
newArr.push(item)
}
})
return newArr
}
console.log(removalRepeatArray(arr));
- 通过数组sort()方法
function removalRepeatArray() {
const newArr = []
//在原数组进行排序
arr.sort()
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== arr[i + 1]) {
newArr.push(arr[i])
}
}
return newArr
}
console.log(removalRepeatArray(arr));
- 通过ES6的Set
这个最简单了 ,这是es6中新的东西
Set是新的数据结构 ,它类似于数组,但是成员的值都是唯一的,没有重复的值
function removalRepeatArray(a) {
return Array.from(new Set(a))
}
console.log(removalRepeatArray(arr));
9.ajax请求数据的方法
未写完,待续