疑问:构造函数的原理
0.JS作用概述
验证表单(以前的网速慢)
页面特效(PC端的网页效果)
移动端(移动web和app)
异步和服务器交互(AJAX)
服务端开发(nodejs)
浏览器工作原理

1.JS组成
JS = ECMAScript + DOM + BOM + 高级
ECMAScript(前身为欧洲计算机制造商协会)JavaScript的语法规范
DOM(Document Object Model 的简称)JavaScript操作网页上元素的API
BOM(Browser Object Model 的简称)JavaScript操作浏览器部分功能的API
1.1输出语句
console.log(“内容”)在控制台打印输出内容
alert(“内容”)弹窗显示内容
document.write(“内容”)在页面书写内容
1.2引入方式
内嵌式(学习期间用)
外链式(实际开发)
注释问题:单行,多行,方法注释等..... 快捷键:ctrl+/ 和ctrl+shift+/
2.变量
2.1命名规则
驼峰命名规则:getElementById/matherAndFather/aaaOrBbbAndCcc
遵从规则:
1.变量命名必须以字母或是下标符号”_”或者”$”为开头。
2.变量名长度不能超过255个字符。
3.变量名中不允许使用空格,首个字不能为数字。
4.不用使用脚本语言中保留的关键字及保留符号作为变量名。
5.变量名区分大小写。(javascript是区分大小写的语言)
6.汉语可以作为变量名。但是不建议使用!!!(low)
2.2变量使用
定义赋值和定义后在赋值
var age = 19;
var age ; age = 19
不建议使用:var age = “张三”; age = 19; 跨类型。
3.数据类型
3.1数据类型划分
使用关键字typeof:查看方法: typeof name 或者 typeof(name)
3.1.1简单数据类型(值类型)
四种: 字符串 数字 布尔 未定义
string number boolean undefined null
3.1.2复杂数据类型(引用类型)
Object、function、Array、Date、RegExp、Error.......
3.1.3字面量
固定的值,让你从“字面上”理解其含义。
数值字面量
var age = 18; // 数值字面量,18为字面值
3.2简单数据类型介绍
3.2.1Number
1.进制
进制包括2进制、8进制(011)、10进制、16进制(0xA)、制等....
2.浮点数
因为精度丢失问题,所以不判断计算后的两个浮点数是否相等。
3.数值范围
由于内存的限制,ECMAScript 并不能保存世界上所有的数值
最小值:Number.MIN_VALUE,这个值为: 5e-324
最大值:Number.MAX_VALUE,这个值为: 1.7976931348623157e+308
无穷大:Infinity
无穷小:-Infinity
4.NaN
a) NaN 非数值(Not a Number的简写)
console.log(“abc”/18); //结果是NaN
Undefined和任何数值计算为NaN;
NaN 与任何值都不相等,包括 NaN 本身
b) isNaN() :任何不能被转换为数值的值都会导致这个函数返回 true
( isNaN译为是否符合一个标准,什么标准呢?不是一个数字的标 准,如果符合了那么就不是一个数字,不符合就是一个数字)
isNaN(NaN);// true
isNaN(“blue”); // true
isNaN(123); // false
3.2.2 string
1.字面量定义方式
用引号时,可单可双,唯独不可一单一双。可用.length看有几个字符。
var name = "zhangsan";
var name = 'zhangsan';
var name = 'zhangsan"; //错误,单引号和双引号要成对出现
2.转译
总结:无法输出的字符,先输出/,在输出字符。(“、\、换行等....)
3.字符串不可变
在内存中不会立刻消失,只能二次赋值,原有的字符在一定时间 内被 垃圾回收器回收。
4.字符串拼接
如果两个变量都是字符串,无论是否包含数字,只要是拼接,那么在前一个后面添加后一个字符串。(+与-情况不同,详情参考数据转换)
3.2.3 Booblean
1.Boolean类型有两个字面量:true和false,区分大小写。(大写不对)
虽然Boolean 类型的字面值只有两个,但 ECMAScript 中所有类型的值都有与这两个 Boolean 值等价的值
2.true
true、除0数字、“something”、Object(任何对象)为true
3.false
false、0 、“”、undefined 、null为false
4.if判断时会把()内的值强行转换成boolean类型进行判断。
3.2.4undefined和null的联系和区别
null和undefined有最大的相似性。看看null == undefined的结果(true)也就更加能说明这点。但是null ===undefined的结果(false)。不过相似归相似,还是有区别的,就是和数字运算时,10 + null结果为:10;10 + undefined结果为:NaN。
任何数据类型和undefined运算都是NaN;
任何值和null运算,null可看做0运算。
4.数据类型转换
一、转换成字符串类型
二、转换成数值类型
三、转换成布尔类型
4.1任何简单类型转换成String(三种方法)
4.1.1变量+“” 或者 变量+“abc”
4.1.2 String(变量)
4.1.3变量.toSting() 注意:undefined和null不可以
Null和undefined无toString方法。
4.2任何简单类型转换成Number
此转换容易产生NaN,一旦被转换的变量中含有非数字字符,都容易出现NaN
4.2.1变量-*/一个数字(有非数字字符会出现NaN)
例:var num1 = “11”- 0; var num2 =“11”* 1;var num =“11”/1;
JS底层做了一个强制类型转换,把字符串转换成了Number进行运算。
4.2.2 Number(变量)(有非数字字符会出现NaN)
var num1 = Number(“18”); 把字符变成了数字。
var num2 = Number(“18.99”); 结果为18.99数字型。(有小数也转换)
4.2.3 parseInt()和parseFloat()(译为取整和取浮点数)
空字符串parseInt()和parseFloat()返回NaN,Number("")返回0
parseInt(变量):如果变量中收割字符为字母则结果为NaN。
否则取出现首个非数字前的整数。
123 = parseInt(“123.123aaaa”);
parseFloat(变量):如果变量中收割字符为字母则结果为NaN。
否则取出现首个非数字前的浮点数。(没有小数取整)
123.123 = parseFloat(“123.123aaaa”);
4.2.4特别提示
Boolean类型中:true数值为1;false为0;
null的数值类型为0;
undefined无数值类型或者为NaN;
4.3任何简单类型转换成Boolean
任何数据类型都可以转换成boolean类型,所以和以往两个转换不同;
4.3.1Boolean(变量)
var bool = Boolean(“1111”); bool为true;
!!变量
第一个逻辑非操作会基于无论什么操作数返回一个与之相反的布尔值
第二个逻辑非操作则对该布尔值求反
于是就得到了这个值真正对应的布尔值
5. 操作符
5.1操作符种类
算数运算符(+—*/...)
一元运算符:正号、负号、++、--、平方等一个变量就能运算
二元运算符:+-*/%等两个变量才能运算
三元运算符: 值1?值2:值3;
逻辑运算符( ||&& ! )(或且非)
比较运算符(<、>、==、>=...)
赋值运算符(=、+=、-=、*=、/=、%=)
5.2优先级
1 ()
2 !、-(负数)、++、-- (正数省略+)(一元运算)
3 *、/、%
4 +、- (加,减)(二元运算)
5 <、<=、<、>= (一级逻辑运算)
6 ==、!=、===、!==、 (二级逻辑运算)
7 && (三级级逻辑运算)
8 ||
9?: (三元运算)
10 =、+=、-=、*=、/=、%= (赋值运算)
5.3&&和||运算
5.3.1&&链接两个boolean类型,有一个是false结果就是false。
链接值不是布尔类型时,按照成布尔类型计算,结果本身不变。(非布尔)
例子: 1 = 2&&1; 0 = 0 && 1; 都是true取后面,都是false取前面。
5.3.2||链接两个boolean类型,有一个是true结果就是true。
链接值不是布尔类型时,按照成布尔类型计算,结果本身不变。(非布尔)
例子: 2= 2||1; 1 = 0 || 1; 都是true取前面,都是false取后面。
6.流程控制
1.顺序结构(程序正常执行流程从上往下,从左往右)(不用研究)
赋值运算时为从右往左执行,且左侧为属性或变量,不取值!!!
2.选择结构
If语句
Switch语句
3.循环结构
for循环
while循环
do...while循环
6.1循序结构
程序正常执行顺序不必过多研究,特殊需求,后续老师特殊讲解。
6.2选择结构
共有两种,if语句和switch语句。If常用,switch为特殊情况使用,判断条件出现的情况特别多的时候用switch,其他时候if语句比较方便。
6.2.1If语句
1.If语句用法有三种
if(条件1){程序1}
if(条件1){程序1}else{程序2}
if(条件1){程序1}else if(条件2){程序2}...else{程序n}
2.三目运算(也叫三元运算)(目或者元代表几个表达式)
三目运算可以替代部分if...else...功能,运算简单,使用方便,代码清晰。
表达式1?值1:值2
6.2.2.Switch语句
switch (值1) {
case value1:
程序1;
break; // break 关键字会导致代码执行流跳出 switch 语句
case value2:
程序2;
break;
default:
程序3;
}
注意:
break可以省略,如果省略,代码会继续执行下一个case
switch 语句在比较值时使用的是全等操作符,因此不会发生类型转换
(例如,字符串 "10" 不等于数值 10)。
6.2.3案例:(可以用if语句实现,下去可以自己练习)
1.判断当天是星期几
2.把百分制转换成优良中可差
6.3循环结构
共3种,for/while/do...while;可根据需求选择使用;
1.遍历数组首选for循环,简单循环使用for。
2.而while循环强调,不记循环次数(不知道循环多少次),首选while。
3.最后do...while循环强调,无论怎样,至少执行一次是,使用do...while。
6.3.1for循环
1.执行流程
for (变量;条件1;条件2){ 执行程序 }
执行过程:变量->条件1->执行程序->条件2->条件1->执行程序.....
直到条件1不成立,跳出循环。
2.三个表达式均为可选,但是必须写分号!!!
for(;;){程序} 死循环;
7.数组
7.1数组的概述
7.1.1为什么学习数组
之前学习的数据类型,只能存储一个值。(字符串为一个值)
我们想存储多个值的时候可以使用数组。(字符串不方便)
比如:存储班级中所有学生的姓名。([“张三”,“李四”,“王五”])
7.1.2数组是什么
数组是一种数据类型。(把很多数据装入一个盒子中,用的时候在取出来)
字面量为[1,2,3]。可以理解为:西瓜皮[],西瓜肉123,西瓜子(,)
7.2数组的定义
7.2.1字面量定义
var arr = [1,2,3];
7.2.2对象定义(数组的构造函数)
var arr = new Array(参数);
参数位置一个数值时为数组长度,多个数值时为数组中的元素。
7.3数组的操作
7.3.1求数组的长度
数组的长度 = 数组名.length;
可以通过修改数组的长度来改变数组中元素的个数,如果改小了,数组从后面删除元素。(伪数组的元素可以修改,但是不能修改长度)
7.3.2获取数组中的元素
数组中的指定元素 = 数组名[索引值];
数组的索引代表的是数组中的元素在数组中的位置,从0开始。
如果获取数组中元素是,数组名[索引值],没有指定索引(元素没那么多),系统不报错,而是给定值为undefined;
7.4 遍历数组(获取并操作数组中的每一个元素)(!!!重点!!!)
var arr = [1,2,3];
for(var i = 0;i
}
7.5 案例:
冒泡排序,从小到大
var arr = [7,6,5,4,3,2,1];
//需求:冒泡排序。
//理论:1.比较轮数n-1。 2.比较次数n-1。 3.符合某个条件交换位置。
//核心:双重for循环。
//步骤:
//1.双重for循环。
//2.指定轮数和次数
//3.判断是否符合标准。如果符合标准交换位置。
console.log(arr);
//每轮比较少比较一次。(每一轮都会比较出一个最大值,然后后一轮没有必要再比较了,所以没比较一轮,就少比较一次。。。)
var m = 0;
var n = 0;//1.双重for循环。(外循环控制轮数)
for(var i=0;i
for(var j=0;j
//从小到大排列顺滑,如果前面的比后面的大,那么交换位置。
if(arr[j] > arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
m++;
}
n++;
}
console.log(arr);
console.log(m);
console.log(n);
7.6调试(打断点)
过去的调试(锻炼逻辑能力)
alert(变量); console.log(变量);
设置断点(项目太大,使用断点方便,清晰)
8.函数基础
8.1函数概述
8.1.1什么是函数
函数就是可以重复执行的代码块。
8.1.2为什么要用函数
因为一部分代码使用次数可能会很多,所以封装起来,需要的时候调用就可以了。
案例:求和;(总是求和)
8.2函数的定义
关键字function。
function 函数名 () { 程序 }
8.3参数
参与运算的变量。
为什么要设置参数?为了增强函数的功能性,和程序员的交互性,和函数的可拓展行。所以我们增加了参数这个概念。
8.3.1形参
形式上参与运算的变量,无实际值,为实参占位置,就像一`个躯壳一样。(可以理解为函数的内部变量外部无法访问)
8.3.2实参
实际参与运算的变量。形参为他占位置,真实参与运算的变量。
8.4返回值
有return函数就有值;没有return函数就没值;
函数程序运行后的结果外部需要使用的时候,我们不能直接给与,需要通过return返回。
总结:函数内部,return后面的值就是返回值;
作用:函数执行后剩下结果就是返回值。
函数执行完毕,会不会留下点儿什么,取决于有没有返回值
var temp = 函数名() = (功能)+ 该函数的返回值;
8.4.1注意
1. 如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined
2. 如果函数使用 return语句,那么跟再return后面的值,就成了函数的返回值
3. 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值 也是:undefined
4. 函数使用return语句后,这个函数会在执行完 return 语句之后停止并立即退 出,也就是说return后面的所有其他代码都不会再执行。
8.5函数名、函数体和函数加载问题(重点记忆)
1、函数名是什么
函数名 == 整个函数。
function fn(){alert(1)};
console.log(fn) == console.log(function fn(){alert(1)});
2、函数加载问题
JS加载的时候,只加载函数名,不加载函数体。所以如果想使用内部的成员变量,需要调用函数。
8.6函数定义
第一种定义方法最强大,定义完毕后,在哪里使用都可以,无位置限制。
后两种定义方法是有局限性的。(使用函数必须在定义函数之后)
第一种
function fn1(){
console.log("我是第一种定义方法!");
}
第二种(匿名函数)
var fn2 = function (){
console.log("我是第二种定义方法!");
}第三种
var fn3 = new Function("console.log('我是第三种定义方法!')");
fn1();
fn2();
fn3();
8.7变量和作用域(隐式全局变量和变量声明提升)
8.7.1变量和作用域(函数中的成员变量需要函数执行后才能使用)
1.全局变量(成员变量)
哪里都可以访问到的变量。
(进入script立即定义的变量和没有var的变量)
2.局部变量
函数内部的变量,只有函数内部可以访问到,外面访问不到。
(函数内部用var定义的变量和形参)
8.7.2隐式全局变量
隐式全局变量就是隐藏的全局变量不好被发现。
function fn(){
var a = b = c = 1; // b和c就是隐式全局变量
}
注意:
function fn(){
var a = b = c = 1; // b和c就是隐式全局变量(等号)
var a = 1; b = 2; c = 3; // b和c就是隐式全局变量(分号)
var a = 1 , b = 2 , c = 3; // b和c就不是隐式全局变量(逗号)
}
8.7.3变量声明提升(出现原因:预解析)
函数中,定义变量在使用变量之后。
值提升变量名,不提升变量值,容易出现undefined。计算后形成NaN。
function fn(){
// var aaa;
console.log(aaa);
var aaa = 1;
}
提前看一眼这个习惯叫什么呢? 预解析!
变量声明提升:在预解析的时候,成员变量和函数,被提升到最高位置,方便其他程序访问。
变量声明提升特点:成员变量只提升变量名,不提升变量值。但是,函数是所有内容全部提升。(function直接定义的)
函数范围内照样会出现变量声明提升
什么情况容易出现变量声明提升:使用变量在定义变量之前。
8.8小知识总结
1.函数不调用不执行
2.函数名就等于(整个函数)
3.加载函数的时候,只加载函数名,不加载函数体
4.参数相当于局部变量
5.就近原则使用变量(预解析也是一样,就近原则取内部的变量)
6.两个平级的函数中的变量不会相互影响(可以使用同样的形参名)
9.函数高级
9.1匿名函数(了解)
1.定义:匿名函数就是没有名字的函数。
2.作用:
不需要定义函数名的时候。(群众演员没必要起名,百万雄师下江南)
书写起来更简便。
3.匿名函数的调用有三种方法:
1.直接调用或自调用。(function(){alert(1)})()
2.事件绑定。
3.定时器。
9.2函数是一种类型(了解)
9.3函数作为参数(了解)回调函数:函数作为参数进行传递和使用。
9.4递归(理解)
递归:就是函数自己调用自己。(懂得)
必须有跳出条件。
10.对象和面向对象
10.1JS中的对象(Object)
10.1.1创建空白对象
var obj = new Object();
10.2构造函数(就是为了创建对象实例)
可以创建对象实例的函数。
区别与普通函数,首字母大写。
10.3创建自定义对象
创建一个对象和属性例子:
var stu = new Object();
var aaa = "age";
对象名.属性
stu.name = "拴柱";
stu.aaa = 19;
对象名[变量]|| 对象名[值]
stu[aaa] = 20;
10.3.1This
1.this只出现在函数中。
2.谁调用函数,this就指的是谁。
3.new People(); People中的this代指被创建的对象实例。
10.3.2 new
1.开辟内存空间,存储新创建的对象( new Object() )
2.把this设置为当前对象
3.执行内部代码,设置对象属性和方法
4.返回新创建的对象
十进制的值 = 位值*进制(位数-1) +位值*进制(位数-1) +位值*进制(位数-1)............
11.对象和面向对象
11.1对象字面量个JSON
var obj = {aaa: 111}; var json = {“aaa”:111};
对象字面量定义方法和json很像,只有一点不同,json的key要求必须加“”;
11.2Json组成
Var json = {“aaa”: 1,“bbb”: 2,“ccc”: 3,“ddd”: 4}
Json由{}和key:value以及逗号组成,三部分。(只有一个键值对key:value时,可以没有逗号)
11.3 For...in...
Var json = {“aaa”: 1,“bbb”: 2,“ccc”: 3,“ddd”: 4}
for(var key in json){
//key代表aaa,bbb.....等
//json[key]代表1,2,3....等
}
11.4 参数和传值问题
简单类型数据做参数,函数内部对参数的修改不应影响外部变量.
简单类型传数值。
复杂类型数据做参数,函数内部对参数的修改会应影响外部变量.
复杂类型传地址。
12. 数组高级API
12.1 学习API的方法
12.1.1侧重点(四点)
调用者:谁调用的。 参数:有无,几个。
返回值:有无,什么类型。 功能:干什么用的。
12.1.2自学方法
1.离线
离线文档(讲师发)
2.在线
W3C (前端标准W3CSchool)
MDN (开发者网站)https://developer.mozilla.org/zh-CN/
百度/谷歌/搜狗。。。
12.2 Array的内置方法
12.2.1判断数组和转换数组。
Instanceof: 是一个关键字。 判断A是否是B类型。
布尔类型值 = A Instanceof B ;
Array.isArray() //HTML5中新增 判断是不是数组
布尔类型值 = Array.isArray(变量) ;
调用者:Array 参数:变量(被检测值) 返回值:布尔类型
toString() //把数组转换成字符串,每一项用,分割
字符串 = 数组.toString();
valueOf() //返回数组对象本身
数组本身 = 数组.valueOf();
Join //根据每个字符把数组元素连起来变成字符串
字符串 = 数组.join(变量);
变量可以有可以没有。不写默认用逗号分隔,无缝连接用空字符串。
12.2.2数组增删和换位置(原数组将被修改)
push() //在数组最后面插入项,返回数组的长度
数组1改后的长度 = 数组1.push(元素1);
pop() //取出数组中的最后一项,返回最后一项
被删除的元素 = 数组1.pop();
unshift() //在数组最前面插入项,返回数组的长度
数组1改后的长度 = 数组1.unshift(元素1);
shift() //取出数组中的第一个元素,返回原来的第一个元素值
被删除的元素 = 数组1.shift();
reverse() //翻转数组(原数组将被反转,返回值也是被反转后的数组)
反转后的数组 = 数组1.reverse();
sort(); //给数组排序,返回排序后的数组。如何排序看参数。
从小到大排序后的数组 = 数组1.sort(function(a,b){
return a-b;
});
无参:按照数组元素的首字符对应的Unicode编码值从小到大排列数组元素。
带参:必须为函数(回调函数--callback)。函数中带有两个参数,代表数组中的 前后元素。如果计算后(a-b),返回值为负数,a排b前面。等于0不动。 返回值为正数,a排b后面。
12.2.3了解方法
concat() //把参数拼接到当前数组
新数组 = 数组1.concat(数组2);
slice() //从当前数组中截取一个新的数组,不影响原来的数组,参数start从0开始,end从1开始
新数组 = 数组1.slice(索引1,索引2);
splice()//删除或替换当前数组的某些项目,参数start,deleteCount,options(要替换的项目)
新数组 = 数组1.splice(起始索引,结束索引,替换内容);
indexOf()、lastIndexOf() //如果没找到返回-1
索引值 = 数组.indexOf/lastIndexOf(数组中的元素);
迭代方法 不会修改原数组
every()、filter()、forEach()、map()、some()
数组/boolean/无 = 数组.every/filter/forEach/map/some(
function(element,index,arr){
程序和返回值;
}
);
//对数组中每一项运行以下函数,如果都返回true,every返回true,如果有一项返回false,则停止遍历 every返回false;不写默认返回false
array.every(function(item,index,arr) {
})
//对数组中每一项运行以下函数,该函数返回结果是true的项组成的新数组
var arr = array.filter(function(item,index,arr) {
});
console.log(arr);
//遍历数组
array.forEach(function(item,index,arr){
});
//对数组中每一项运行以下函数,返回该函数的结果组成的新数组
var arr = array.map(function(item,index,arr) {
return "\"" + item + "\"";
})
//对数组中每一项运行以下函数,如果该函数对某一项返回true,则some返回true
var b = array.some(function(item,index,arr) {
if (item == "ww") {
return true;
}
return false;
});
12.2.4 清空数组
var array = [1,2,3,4,5,6];
array.splice(0,array.length); //删除数组中所有项目
array.length = 0; //length属性可以赋值,其它语言中length是只读
array = []; //推荐
12.3 Date/Math/简单数据类型
12.4 js构造函数原理
function Num(aaa){
this["[[PrimitiveValue]]"] = num/1;
return aaa/1;
}
例子:
function Book(name, price) {
this.name = name;
this.price = price;
}
var java = new Book('Master Java', 82);
区别与普通函数,首字母大写。
1.当使用new关键字来调用构造函数时,执行上下文从全局变量对象(window)变成一个空的上下文,这个上下文代表了新生成的实例。因此,this关键字指向当前创建的实例。
2.默认情况下,如果你的构造函数中没有返回任何内容,就会返回this----当前的上下文,也就是你当前创建的对象。要不然就返回任意非原始类型的值。而普通的函数如果没有明显的返回值将返回undefined。
3.实际上构造函数就是个普通的函数,可以当作普通函数调用的,例如var result = Book();,当然结果是undefined。区别在于函数中this的指向。
12.5 实参和形参
fn(1,2);
fn(1,2,3);
fn(1,2,3,4,5);
function fn(a,b){
只在函数中使用,实参的数组。
arguments[0] = 0;
console.log(arguments);
伪数组:不能修改长短的数组。(可以修改元素,但是不能变长变短)
arguments.push(1);
console.log(arguments instanceof Array);
//形参个数
console.log(fn.length);
//实参个数
console.log(arguments.length);
arguments.callee整个函数。函数名。
console.log(arguments.callee);
}