版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Stream_who/article/details/82961505
一、基础概念
1.概念:
1)JavaScript是一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型
2)它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML网页上使用,用来给HTML网页增加动态功能,添加交互行为
3)JavaScript 是可插入 HTML 页面的编程代码, 插入 HTML 页面后,可由所有的现代浏览器执行
4)javaScript是一种解释性语言,边执行边解释
5) 是一种表述语言,也是一种基于对象(Object)和事件驱动(EventDriven)的,安全性好的脚本语言,运行在客户端,从而减轻服务器端的负担
2.组成
1)ECMAScript 描述了该语言的语法和基本对象
2)文档对象模型(DOM) 描述处理网页内容的方法和接口(文档指的就是网页,把网页变成一个JS可以操作的对象;给了JS可以操作页面元素的能力)
3)浏览器对象模型(BOM) 描述与浏览器进行交互的方法和接口(给了JS操作浏览器的能力)
3.引入方式
1)使用<Script>标签直接嵌入网页(一般放在body标签结束之前)
2)使用<Script>标签直接嵌入网页
4.语法
1) 一个字面量是一个常量,如 3.14
2) 区分大小写
3) 每行代码以分号结束
5.操作符
1) 算术: 加减乘除、取模(求余数%);
2) 赋值:= , +=,
3) 关系: <</span>, >, <=, >=, ==, ===,!=, !==
4) 逻辑: && 与, ||或,!取反;
5) 运算符优先级:();
6.程序流程控制
1) 判读: if ,switch,? :
2) 循环: for, while, do...while
3) 跳出: break(终止整个循环), continue(终止本次循环,继续下次循环;只跳过当次;)
4) 什么是真,什么是假
(1)真: true, 非0数字,非空字符串包括空格,非空对象
(2)假: false, 数字0,空字符串,空对象null, undefined
7.严格模式(strict)
1) 声明: "use strict";
2)如何调用
(1)针对整个脚本文件
将"use strict"放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。如果这行语句不在第一行,则无效,
整个脚本以"正常模式"运行。如果不同模式的代码文件合并成一个文件,这一点需要特别注意
(2)针对单个函数
将"use strict"放在函数体的第一行,则整个函数以"严格模式"运行
(3)脚本文件的变通写法
因为第一种调用方法不利于文件合并,所以更好的做法是,借用第二种方法,将整个脚本文件放在一个立即执行的匿名函数之中
3)在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明
二、数据类型
1.基本数据类型
1)Undefined 未定义
(1)undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined
2)Null 空对象指针 (特例: console.log(typeof (null)); //object)题
(1)Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null时会返回"object"的原因
(2)var car={ } car==null 是false的
(3)undefined == null 实际上,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true
(4)尽管null和undefined有这样的关系,但它们的用途完全不同。无论在什么情况下都没有必要把一个变量的值显式地设置为undefined,可是同样的规则对null却不适用
(5)只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null值。这样做不仅可以体现null作为空对象指针的惯例,而且也有助于进一步区分null和undefined
3)Boolean Boolean类型
该类型只有两个字面值:true和false。这两个值与数字值不是一回事,因此true不一定等于1,而false也不一定等于0
(1)为false的情况
a.undefined
b.0
c.null
d.""
e.NaN
f.false
4)Number Number类型
(1)这种类型用来表示整数和浮点数值,还有一种特殊的数值,即NaN(非数值 Not a Number)。这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)
(2)在其他编程语言中,任何数值除以0都会导致错误,从而停止代码执行。但在JavaScript中,任何数值除以0会返回NaN,因此不会影响其他代码的执行
(3)NaN本身有两个非同寻常的特点。首先,任何涉及NaN的操作(例如NaN/10)都会返回NaN,这个特点在多步计算中有可能导致问题
(4)其次,NaN与任何值都不相等,包括NaN本身,如 alert(NaN == NaN); //false 会返回false
(5)isNaN()在接收一个值之后,会尝试将这个值转换为数值,任何不能被转换为数值的值都会导致这个函数返回true
alert(isNaN(NaN)); // true
alert(isNaN(10)); // false(10是一个数值)
alert(isNaN("10")); // false(可能被转换为数值10)
alert(isNaN("blue")); // true(不能被转换为数值)
alert(isNaN(true)); // false(可能被转换为数值1)
5)String 字符串
(1)String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由单引号(')或双引号(")表示
(2)任何字符串的长度都可以通过访问其length属性取得
2.对象
1)一切(引用类型)都是对象,对象是属性的集合
2)对象通过函数创建
3) 一切皆对象,{ 内容 },函数、数组、对象、new Number(10)都是对象
3.一般来说,值类型的类型判断用typeof,引用类型的类型判断用instanceof
1)typeof
console.log(typeof(x)); // undefined
console.log(typeof(10)); // number
console.log(typeof('abc')); // string
console.log(typeof(true)); // boolean
console.log(typeof(function () { })); // function
console.log(typeof([1, 'a', true])); // object
console.log(typeof ({ a: 10, b: 20 })); // object
console.log(typeof (null)); // object
console.log(typeof (new Number(10))); // object
2) instanceof
var fn = function () { };
console.log(fn instanceof Object); // true
三、原型
1)对象都是通过函数创建的
2)每个函数都有一个属性叫做prototype(只有函数对象有原型!!!),每个对象都有一个__proto__,可称为隐式原型
3)prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做constructor的属性,指向这个函数本身
4)Object.prototype里面有很多其他属性(hasOwnProperty,toString,valueOf等)
5)每个对象都有一个__proto__属性,指向创建该对象的函数的prototype(而不是这向这个对象,是对象.propttype)
6)Object.prototype却是一个特例——它的__proto__指向的是null(我所理解的“根”节点)
7)访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链
8) 原型是为继承服务的,可以继承自原型链中的方法和属性,要自己在prototype加东西的时候判断下原型链中有没有
9)每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象的函数的prototype。即:fn.__proto__ === Fn.prototype
四、作用域与执行上下文
1.作用域
1)javascript是没有块级作用域的。javascript除了全局作用域之外,只有函数可以创建的作用域
2)JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面(声明提升)
3)作用域有上下级的关系,上下级关系的确定就看函数是在哪个作用域下创建的
4)作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突
5) 作用域在函数定义时就已经确定了。而不是在函数调用时确定(调用时应该是执行上下文)
作用域中变量的值是在执行过程中产生的确定的,而作用域却是在函数创建时就确定了
6)作用域只是一个“地盘”,一个抽象的概念,其中没有变量。要通过作用域对应的执行上下文环境来获取变量的值
7)如果要查找一个作用域下某个变量的值,就需要找到这个作用域对应的执行上下文环境,再在其中寻找变量的值
8)自由变量(就是该函数直接用在该函数下没有声明的变量)要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”
这就跟作用域链有关了
9)函数内部声明变量的时候,一定要使用var命令。如果不用的话,实际上声明了一个全局变量
2.执行上下文(在执行代码之前,把将要用到的所有的变量都事先拿出来,有的直接赋值了,有的先用undefined占个空)
1)全局代码的上下文环境(目前所知,部分先后)
(1)普通变量
如: var a = 10; 声明(默认赋值为undefined)
var b = function(){ };
(2)函数声明
如: function fn() { } 赋值
(3)this 赋值
2)如果代码段是函数体,那么在此基础上需要附加
普通变量,函数声明,this
(1)参数 赋值
(2)arguments 赋值
(3)自由变量的取值作用域 赋值
3)执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境。当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到上一级执行上下文
4)处于活动状态的执行上下文环境只有一个,其实这是一个压栈出栈的过程——执行上下文栈
5)执行上下文后,代码执行
五、函数
1.函数定义
1)声明式定义
(1) function add(m,n) {
alert(m+n);
}
(2)这种方式等同于构造一个Function类的实例的方式
var add = new Function("m", "n", "alert(m+n);");
(3)Function类构造方法的最后一个参数为函数体:"alert(m+n);",前面的都是函数的形参,参数必须是字符串形式的:"m","n"
2)变量匿名函数
(1) var myfun = function(){
cnonsole.log("我把匿名函数赋值给变量");
}
(2) 将一个匿名函数赋值给变量add
3)将函作为一个对象
(1) var obj = {
funName : function(){
alert('这个必须放在一个对象内部,放在外边会出错!');
}
}
4) 无名称匿名函数
(1)在函数声明时,在后面紧跟参数。Js语法解析此函数时,里面代码立即执行
(2)试用于只需执行一次的。如浏览器加载完,只需要执行一次且后面不执行的功能
(3) (function (p1) {
alert(p1);
})(1);
2.调用方式
1)普通的函数调用
alert("hello");
add(2);
var result = add(1, 2);
2) 方法调用(方法就是将一个函数赋给一个对象的属性)
obj.funName("hh");
3) 构造函数调用
function User(name) {
this.name=name;
console.debug(this);
}
var user = new User('张三');
4) 通过 call() 和 apply() 间接调用(其他形式函数调用的本质其实都是这种方法,只不过是语法糖)
showName.call(user);
3.this(this 总是指向调用该函数的对象)
1) 函数有所属对象时:指向所属对象
myObject.getValue();
2) 函数没有所属对象:指向全局对象(非stric模式下,stric模式下为undefined)
add();
3) 构造器中的 this:指向新对象
function User(name) {
this.name=name;
console.debug(this); // this指向user
}
var user = new User('张三');
4)apply 和 call 调用以及 bind 绑定:指向绑定的对象
foo.apply(myObject)
4.apply,call和bind
1) call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),
我们可以借助call或apply用其它对象的方法来操作
2) apply、call作用完全一样,只是接受参数的方式不太一样
var func = function(arg1, arg2) {
};
(1)func.call(myObject, arg1, arg2); // 第一个是传入的对象赋值给this,后面是参数
(2)func.apply(myObject, [arg1, arg2]) // 同,但参数是以数组的形式传
3)JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过arguments 这个伪数组来遍历所有的参数
4)bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数
var a = {
user:"追梦子",
fn:function(e,d,f){
console.log(this.user); //追梦子
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
5)三者区别
(1)apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
(2)apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
(3)apply 、 call 、bind 三者都可以利用后续参数传参;
(4)bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用
5.闭包(跟自由变量有关)
1.分类:函数作为返回值(通常是这种),或者函数作为参数
2.闭包就是能够读取其他函数内部变量的函数,定义在一个函数内部的函数
3.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中(占用资源)
4.闭包会在父函数外部,改变“父”函数内部变量的值
6.构造函数
1)调用:构造函数需要使用new运算符调用,如果构造函数没有参数可以省略小括号,比如new Object
2)构造函数的this会被绑定到创建的对象实例上
3)构造函数名称通常首字母要大写
4)默认不用return返回值 构造函数是不需要用return显式返回值的,默认会返回this,也就是新的实例对象
5) 在 JavaScript 中,构造器其实就是一个普通的函数。当使用 new 操作符 来作用这个函数时,它就可以被称为构造方法(构造函数)
6)使用new关键字发生了什么:
比如:var prince=new Prince("charming",25);
(1)第一步,创建一个空对象。 var prince={}
(2)第二步,将构造函数Prince()中的this指向新创建的对象prince
(3)第三步,将prince的_proto_属性指向Prince函数的prototype,创建对象和原型间关系
(4)第四步,执行构造函数Prince()内的代码
7) 构造函数有return值怎么办
(1)return的是五种简单数据类型:String,Number,Boolean,Null,Undefined。 这种情况下,忽视return值,依然返回this对象
(2)return的是Object 这种情况下,不再返回this对象,而是返回return语句的返回值
8) 在构造函数内部,this指向的是构造出的新对象。用this定义的变量或函数/方法,就是实例变量或实例函数/方法。需要用实例才能访问到,不能用类型名访问。
如: prince.age;//25 Prince.age;//undefined
参考网址
都在JavaScript(下)
注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激