浏览器的主要组件为 (1.1):javascript
参考文献css
ECMAScript:JavaScript的语法标准html
ECMA是European Computer Manufacturers Association的缩写,即欧洲计算机制造商协会前端
ECMAScript是ECMA制定的脚本语言的标准,规定了一种脚本语言实现应该包含的基本内容html5
Javascript是脚本语言的一种,因此Javascript也必须遵照ECMAScript标准,包含ECMAScript标准中规定的基本内容java
DOM(Document Object Model):JavaScript操做网页上的元素(标签)的APInode
BOM(Browser Object Model):JavaScript操做浏览器的部分功能的API程序员
1.CSS书写格式web
行内样式: 写在标签内部数据库
内嵌样式(内联样式) : 写在一对head-style标签中
外链样式: 写在一个单独的.css文件中, 再导入进来
2.JavaScript书写格式
行内样式: 写在标签内部
内嵌样式(内联样式) : 写在一对head-script标签中
外链样式: 写在一个单独的.js文件中, 再导入进来
3.JavaScript书写格式注意点
不推荐直接将JavaScript代码书写到标签内部
默认状况下浏览器会从上至下的解析网页, 因此若是将JavaScript写到一对head标签中, 而且须要经过JavaScript代码操做界面上的元素, 那么就不能直接书写JavaScript代码, 不然无效
window.onload = function () {
var oDiv = document.querySelector("div");
var text = oDiv.innerText;
alert(text);
}
复制代码
若是经过外链式导入.js文件, 而且须要在.js文件中操做界面上的元素, 并且是在head标签中导入的, 必须在.js文件中加上window.onload. 若是是在body结束标签前面导入的, 那么就不用添加window.onload
若是须要在一对script标签中编写JavaScript代码, 那么就不能同时经过script标签再导入其它的.js文件, 不然书写的JavaScript代码无效
1.经过弹窗的形式来输出
alert(须要输出的内容);
confirm(须要输出的内容);
prompt(须要输出的内容);
注意点:
若是须要输出的内容不是数字, 那么就必须经过单引号或者双引号括起来
在JavaScript中是严格区分大小写的, alert()和ALERT()不是一回事
在编写JavaScript代码的时候, 必定要记住每一句代码后面都须要添加一个分号, 而且这个分号必须是英文的分号
咱们会发现有时候不写分号程序也可以运行, 这里并非由于不须要分号, 而是浏览器自动帮助咱们添加了分号, 浏览器自动添加会消耗必定的性能, 而且有可能会添加错误
2.经过网页内容区域的形式来输出
注意点:
若是须要输出的内容不是数字, 那么就必须经过单引号或者双引号括起来
3.经过开发者工具控制台的形式来输出
console.log(须要输出的内容); // 普通输出
console.warn(须要输出的内容); // 警告输出
console.error(须要输出的内容); // 错误输出
注意点:
若是须要输出的内容不是数字, 那么就必须经过单引号或者双引号括起来
1.什么是常量?
常量表示一些固定不变的数据
现实生活中人的性别其实就能够看作是常量, 生下来是男孩一生都是男孩, 生下来是女孩一生都是女孩
2.JavaScript中常量的分类
整型常量
实型常量
字符串常量
布尔常量
自定义常量
1.什么是变量?
变量表示一些能够被修改的数据
在现实生活中超市的储物格就是变量, 在不一样的时间段里面, 储物格中存储的数据也不同
2.如何定义一个变量
在JavaScript中能够经过定义变量的方式来生成储物格, 也就是告诉浏览器, 咱们须要一块内存空间
var 变量名称;
复制代码
3.如何使用变量
使用变量就是往申请的那块内存空间中存储数据, 和获取存储的数据
3.1如何存储数据
变量名称 = 须要存储的数据;
能够将等号右边须要存储的数据放到等号左边变量申请的那块存储空间中
3.2如何获取存储在变量中的数据
变量名称
// 定义一个变量
var num;
// 往变量中存储数据
num = 123;
// 从变量中获取存储的数据
console.log(num);
复制代码
4.如何修改变量中存储的数据
在JavaScript中想要修改变量中存储的数据, 只须要再次给变量直接赋值便可
num = 666;
console.log(num);
复制代码
5.在JavaScript中第一次给变量赋值, 咱们称之为"变量的初始化"
var num;
num = 321; // "变量的初始化"
num = 888; // 不是"变量的初始化"
复制代码
6.若是一个变量没有进行初始化, 那么变量中存储的是什么呢?
在JavaScript中若是定义了一个变量,可是没有进行初始化, 那么变量中存储的是undefined
var num;
console.log(num);
复制代码
7.给变量初始化有不少种形式
var num;
复制代码
var value = 666; // 定义的同时初始化
复制代码
8.定义变量的其它格式
同时定义多个变量的格式,格式: var 变量名称1, 变量名称2, .... ;
var num, value; // 同时定义两个变量
复制代码
9.初始化变量的其它格式
若是在企业开发中对多个变量初始化的值都是同样的, 那么咱们能够经过:变量名称1 = 变量名称2 = 变量名称... = 初始化值;
num = value = 123;
// 同时对num和value进行初始化, num和value中存储的数据都是123
复制代码
10.定义多个变量的同时给多个变量分别初始化
var num = 123, value = 666;
复制代码
11.注意点
var num;
var value;
num = 123;
value = num; // 将Num中的值拷贝一份给value
console.log(num);
console.log(value);
复制代码
var num = 666;
num = 888;
// 若是num前面没有var, 那么就是修改变量中存储的值
var num = 888;
// 若是num前面有var, 那么就不是修改变量中存储的值, 而是从新定义一个新的变量
复制代码
console.log(num);
var num = 123;
预处理以后的代码
var num;
console.log(num); // undefined
num = 123;
复制代码
12.ES6变量定义
为了解决老版本标准的的两个注意点:
格式:
ES6以前: var 变量名称;
ES6开始: let 变量名称;
// 定义一个变量
let num;
// 给变量初始化
num = 666;
// 取出存储的数据
console.log(num);
// 修改变量中存储的数据
num = 888;
// 取出存储的数据
console.log(num);
// var num = 123;
// var num = 888;
let num = 123;
let num = 888; //会明确的报错
console.log(num);
console.log(num);
var num = 123; undefined
console.log(num);
let num = 123; 报错
复制代码
什么是关键字?
关键字 | |||
---|---|---|---|
break | do | instanceof | typeof |
case | else | new | var |
catch | finally | return | void |
continue | for | switch | while |
default | if | throw | delete |
in | try | function | this |
with | debugger | false | true |
null |
什么是保留字?
保留字 | |||
---|---|---|---|
class | enum | extends | super |
const | export | import | implements |
let | private | public | yield |
interface | package | protected | static |
什么是标识符?
命名规则(必须遵照):
命名规范(建议遵照):
1.什么是JS的注释?
和HTML/CSS的注释同样, 都是用来注解解释某一段程序的含义的, 都是用来提高代码的阅读性的, 都是为了方便程序员之间沟通的
2.JS注释的格式
3.JS中注释的嵌套规则
/*
被注释的内容
/*
*/
*/
复制代码
1.什么是数据?
2.数据分类
静态数据
动态数据
既然硬盘的存储空间这么大,为什么不把全部的应用程序加载到硬盘中去执行呢?
静态数据和动态数据的相互转换:也就是从磁盘加载到内存
动态数据和静态数据的相互转换:也就是从内存保存到磁盘
数据的计量单位
3.数据类型概述
做为程序员最关心的是内存中的动态数据,由于咱们写的程序就是在内存中的,程序在运行过程当中会产生各类各样的临时数据,为了方便数据的运算和操做,JavaScript对这些数据进行了分类,提供了丰富的数据类型
基本数据类型
Number 数值类型
在JavaScript中不管是整数仍是小数都是属于数值类型的
String 字符串类型
在JavaScript中不管是经过单引号仍是经过双引号括起来的内容都是属于字符串类型的
Boolean 布尔类型
在JavaScript中布尔类型比较特殊, 只有两个取值true/false
Undefined 未定义类型
在JavaScript中未定义类型比较特殊, 只有一个取值undefined
Null 空类型
引用数据类型
在JavaScript中为了方便咱们检测某一种数据是属于哪种数据类型的, JavaScript提供了一个名称叫作typeof的操做符
let res = typeof 123;
console.log(res); >>number
let num;
console.log(num);
// 以上代码的含义是输出num变量中保存的数据
// 因为没有给num这个变量进行初始化, 因此这个变量中保存的数据默认是undefined(取值)
let res = typeof num;
console.log(res);
// 利用typeof检查num中保存的数据是什么类型的
// 也就是说利用typeof检查undefined是属于什么类型的(数据类型)
复制代码
1.转换为字符串类型
let value = 123;
console.log(value);
// 在谷歌浏览器的控制台中若是是Number类型是蓝色的
// 如下代码的含义: 将value变量中存储的数据拷贝一份, 而后将拷贝的数据转换为字符串以后返回
let str = value.toString();
console.log(str);
// 在谷歌浏览器的控制台中若是是String类型是灰色的
// 注意点: 不能使用常量直接调用toString方法, 由于常量是不能改变的
let str2 = 123.toString();
复制代码
let str = 123 + '';
console.log(str); >>'123'
console.log(typeof str); >>String
复制代码
2.转换为数值类型
String >> 数值
Boolean >> 数值
undefined >> 数值
转换以后是NaN
null >> 数值
转换以后是0
空字符串/false/null转换以后都是0,字符串中不只仅是数字/undefined转换以后是NaN,其它的正常转换
转换方法
let str = "123";
console.log(str); >>"123"
console.log(typeof str); >>String
let num = Number(str);
console.log(num); >>123
console.log(typeof num); >>Number
复制代码
经过数学运算中的+号和-号来转换
虽然经过+/-均可以将其它类型转换为数值类型, 可是-会改变数值的正负性
底层本质上就是调用了Number函数
let str = "123";
let num = +str;
let num = -str;
复制代码
parseInt(须要转换的字符串)/parseFloat(须要转换的字符串)
从左至右的提取数值, 一旦遇到非数值就会当即中止,若是尚未提取到数值, 那么就返回NaN
parseInt/parseFloat都会将传入的数据当作字符串来处理
let str = "3.14px";
let num = parseFloat(str);
console.log(num); >>3.14
console.log(typeof num); >>Number
let value = true;
let num = parseInt(value); // parseInt("true");
console.log(num); >>NaN
console.log(typeof num); >>Number
复制代码
3.转换为布尔类型
let num = NaN;
console.log(typeof num); >>number
let flag = Boolean(num);
console.log(flag); >>false
console.log(typeof flag); >>boolean
复制代码
简介
运算符也叫操做符。经过运算符能够对一个或多个值进行运算,并获取运算结果。
好比:typeof 就是运算符,能够来得到一个值的类型。它会将该值的类型以字符串的形式返回
+
、*
、/
、(
都是运算符,而(3+5)/2
则是表达式。
优先级和结合性
优先级 | 运算符 | 说明 | 结合性 |
---|---|---|---|
1 | [] 、. 、() |
字段访问、数组索引、函数调用和表达式分组 | 从左向右 |
2 | ++ -- -~!delete new typeof void | 一元运算符、返回数据类型、对象建立、未定 义的值 | 从右向左 |
3 | *、/、% | 相乘、相除、求余数 | 从左向右 |
4 | +、- | 相加、相减、字符串串联 | 从左向右 |
5 | <<、>>、>>> | 左位移、右位移、无符号右移 | 从左向右 |
6 | <、<=、>、>=、instanceof | 小于、小于或等于、大于、大于或等于、是否 为特定类的实例 | 从左向右 |
7 | ==、!=、===、!== | 相等、不相等、全等,不全等 | 从左向右 |
8 | & | 按位“与” | 从左向右 |
9 | ^ | 按位“异或” | 从左向右 |
10 | | | 按位“或” | 从左向右 |
11 | && | 短路与(逻辑“与”) | 从左向右 |
12 | || | 短路或(逻辑“或”) | 从左向右 |
13 | ?: | 条件运算符 | 从右向左 |
14 | =、+=、-=、*=、/=、%=、&=、|=、^=、<、<=、>、>=、>>= | 混合赋值运算符 | 从右向左 |
15 | , | 多个计算 | 按优先级计算,而后从右向左 |
1.什么是算术运算符?
算术运算符 | |
---|---|
+ | 加、字符串链接 |
- | 减 |
* | 乘 |
/ | 除 |
% | 获取余数(取余) |
() | 括号,优先级 |
2.算术运算符的优先级和结合性
let result = 10 % 4;
console.log(result); >>2
复制代码
3.注意点
result1 = true + 1; // 2 = 1+ 1
result2 = true + false; // 1 = 1+ 0
result3 = 1 + null; // 1 = 1+ 0
result4 = 100 - '1' // 99
复制代码
result1 = 1 + 2 + '3' // 33
result2 = '1' + 2 + 3; // 123
复制代码
-
、*
、/
运算时都会自动转换为Numberlet res = -10 % 3; // -1
复制代码
1.什么是赋值运算符?
2.优先级和结合性
//因为算数运算符的优先级高于赋值运算符因此会先计算1 + 1, 而后再赋值给res
let res = 1 + 1;
// 因为赋值运算符的结合性是右结合性, 因此会先将3赋值给num2, 而后再将Num2中的值赋值给num1
let num1, num2;
num1 = num2 = 3;
复制代码
1.什么是自增自减运算符?
2.自增
a++
和++a
。a++
仍是++a
,都会当即使原变量的值自增1。a
是变量,而a++
和++a
是**表达式a++
的值等于原变量的值(a自增前的值)++a
的值等于新值 (a自增后的值)3.自减:同上
var n1=10;
var n2=20;
var n = n1++; //n1 = 11 n1++ = 10
console.log('n='+n); // 10
console.log('n1='+n1); //11
n = ++n1 //n1 = 12 ++n1 =12
console.log('n='+n); //12
console.log('n1='+n1); //12
n = n2--;// n2=19 n2--=20
console.log('n='+n); //20
console.log('n2='+n2); //19
n = --n2; //n2=18 --n2 = 18
console.log('n='+n); //18
console.log('n2='+n2); //18
复制代码
//正式由于关系运算符是左结合性, 因此不能利用关系运算符来判断区间
let res = 10 > 5 > 3; // true > 3; 1 > 3
let res = 10 <= 25 <= 20; // true <= 20 1 <= 20
复制代码
关系运算符 | |
---|---|
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 等于 |
=== | 全等于 |
!= | 不等于 |
!== | 不全等于 |
let res= 1 > true; // 1 > 1
let res= 1 > false; // 1 > 0
let res= 1 > null; // 1 > 0
let res= 1 > '10'; // 1 > 10
复制代码
console.log(10 <= 'hello'); //false
复制代码
parseInt()
// 比较两个字符串时,比较的是字符串的字符编码,因此可能会获得不可预期的结果
console.log('56'>'123'); //true
console.log('b' > 'a'); // 0062 > 0061
复制代码
console.log('6'== 6); >>true
console.log(true == '1'); >>true
console.log(0 == -0); >>true
console.log(null == 0); >>false
console.log(undefined == null); >>true
console.log(NaN == NaN); >>false
console.log(isNaN(b)); >>false
复制代码
===
。全等不会作类型转换==
的反面是!=
,===
的反面是!==
console.log('6' === 6); >>false
console.log(6 === 6); >>true
复制代码
分类
&&
与(且):两个都为真,结果才为真。
||
或:只要有一个是真,结果就是真。
!
非:对一个布尔值进行取反。
注意事项
左结合性(从左至右的运算),&&的优先级高于||
能参与逻辑运算的,都是布尔值
逻辑短路
&&
属于短路的与,若是第一个值为false,则不会看第二个值||
属于短路的或,若是第一个值为true,则不会看第二个值true && alert('hhh'); //hhh
true || alert('hhh'); //true
复制代码
非布尔值运算
var result = 5 && 6; //true && true
console.log(result); //6
复制代码
实际开发(作容错处理 )
// 当成功调用一个接口后,返回的数据为 result 对象。这个时候,咱们用变量 a 来接收 result 里的图片资源。一般的写法是这样的:(这里我只是举个例子)
if (result.resultCode == 0) {
var a = result && result.data && result.data.imgUrl || 'http://img.smyhvae.com/20160401_01.jpg';
}
// 上方代码的意思是,获取返回结果中的result.data.imgUrl这个图片资源;若是返回结果中没有 result.data.imgUrl 这个字段,就用 http://img.smyhvae.com/20160401_01.jpg 做为兜底图片。这种写法,在实际开发中常常用到。
复制代码
// 利用逗号运算符同时定义多个变量
let a,b;
// 利用逗号运算符同时给多个变量赋值
a = 10,b = 5;
let res = ((1+1),(2+2),(3+3));
console.log(res); //6
复制代码
基本概念
1.条件判断语句
if(条件表达式){
条件为真时执行语句;
}
let age = 19;
if(age >= 18){
console.log('开网卡');
}
console.log('卖饮料');
复制代码
3.条件分支语句
if(条件表达式){
条件为真时执行语句;
}else{
条件为假时执行语句;
}
if(条件表达式1){
条件1为真时执行语句;
}else if(条件表达式2){
条件为1不知足时执行语句;
}else if(条件表达式3){
条件1,2不知足时执行语句;
}else{
条件1,2,3都布知足时执行语句;
}
复制代码
3.注意点
if(null){
console.log('a');
}
console.log('b');
>>b
复制代码
let num = 10;
if(5 == num){
console.log('a');
}
复制代码
if(false)
console.log('a');
console.log('b'); >>b
复制代码
if(false);
{
console.log('a');
console.log('b');
}
>>;
复制代码
if(true){
if(false){
console.log('a');
}else{
console.log('b');
}
}else{
if(false){
console.log('c');
}else{
console.log('d');
}
}
复制代码
if(0)
if(1)
console.log('a');
else
console.log('b');
else
if(1)
console.log('c');
else
console.log('d');
复制代码
在企业开发中, 若是条件知足以后只有一句代码须要执行, 那么就使用三元运算符
在企业开发中, 若是条件知足以后有多句代码须要执行, 那么就使用选择结构
let num = prompt('请输入');
num % 2 === 0 ? alert('yes') : alert('no');
if(num % 2 === 0){
alert('yes');
num = 666;
}else{
alert('no');
num = 123;
}
console.log(num);
复制代码
switch(表达式){
case 表达式1:
语句1;
break;
case 表达式2:
语句2;
break;
......
default:
前面全部case都不匹配执行的代码;
break;
}
复制代码
会从上至下的依次判断每个case是否和()中表达式的结果相等, 若是相等就执行对应case后面的代码, 若是前面全部的case都不匹配, 那么就会执行default后面的代码
而且全部的case和default只有一个会被执行, 而且只会被执行一次
注意点:
let num = 123;
switch (num){
case'123':
console.log('字符串123');
break;
case 123:
console.log('数值123');
beak;
default:
console.log('other');
break;
}
复制代码
// let num = 123;
// switch (num) { // 变量
// switch (123) { // 常量
switch (122 + 1) { // 表达式
case 123:
console.log("数值的123");
break;
default:
console.log("Other");
break;
}
复制代码
let num = 123;
switch (123) {
// case 123: // 常量
// case num: // 变量
case 100 + 23: // 变量
console.log("数值的123");
break;
default:
console.log("Other");
break;
}
复制代码
let num = 1;
switch (num) {
case 1:
console.log("1");
break;
case 2:
console.log("2");
break;
default:
console.log("Other");
break;
}
复制代码
let num = 7;
switch (num) {
// default:
// console.log("Other");
// break;
case 1:
console.log("1");
break;
default:
console.log("Other");
break;
case 2:
console.log("2");
break;
}
复制代码
let num = 7;
switch (num) {
case 1:
console.log("1");
break;
case 2:
console.log("2");
break;
}
复制代码
if和switch如何选择
需求: 要求判断一个数是不是大于100的数
let num = 20;
if(num > 100){
alert('大于100的数');
}else{
alert('不大于100的数');
}
复制代码
1.if的格式
if(条件表达式){
条件知足执行的语句;
}
if的特色: 只有条件表达式为真才会执行后面{}中的代码,大括号中的代码只会被执行一次
2.while的格式
while(条件表达式){
条件知足执行的语句;
}
while的特色: 只有条件表达式为真才会执行后面{}中的代码,大括号中的代码有可能会被执行屡次
复制代码
let num = 1;
while(num <= 10){
console.log('发射子弹' + num);
num++;
}
复制代码
注意点
while(true){
console.log('123');
}
复制代码
while(1){
console.log('被执行了');
}
复制代码
和if同样while 后若是只有一条语句它能够省略大括号,和if同样若是省略了后面的{}, 那么只有紧随其后的那条语句受到控制
和if同样, 不能在()后面写分号 ;
最简单死循环写法
while(1);
复制代码
while循环的格式
while(条件表达式){
须要重复执行的代码;
}
while循环的特色: 只有条件表达式为真, 才会执行循环体
dowhile循环的格式
do{
须要重复执行的代码;
}while(条件表达式);
dowhile循环的特色: 不管条件表达式是否为真, 循环体都会被执行一次
复制代码
while和do while如何选择
需求: 要求用户输入密码, 判断输入密码是否正确(假设正确密码是123456)
let pwd = prompt('请输入密码');
while(pwd !== '123456'){
pwd = prompt('请输入密码');
}
alert('欢迎回来');
let pwd = -1;
do{
pwd = prompt('请输入密码');
}while(pwd !== '123456');
alert('欢迎回来');
复制代码
1.在JavaScript中定义变量有两种方式
2.两种定义变量方式的区别
var
var num=123;
var num=456;
console.log(num); >>456
复制代码
console.log(num);
var num=123; >>undefined
复制代码
let
let num=123;
let num=456; >>报错
//只要出现了let, 在相同的做用域内, 就不能出现同名的变量
let num = 123;
var num = 456; // 会报错
var num = 123;
let num = 456; // 会报错
{
let num=123;
{
let num=456; // 不会报错
}
}
复制代码
console.log(num);
let num=123; >>报错
复制代码
3.什么是全局变量和局部变量
4.区别
全局变量
局部变量,
{
var num=123;
}
console.log(num); //不会报错
复制代码
{
let num=123;
}
console.log(num); //会报错
复制代码
1 2/5 4/7
for(初始化表达式;条件表达式;循环后增量表达式){
3/6
须要重复执行的代码;
}
复制代码
1.特色
2.执行流程
for(let num = 1;num <= 10;num++){
console.log('发送子弹'+num);
}
复制代码
3.注意点
while(){
console.log('123');
}
>>报错
for(;;){
console.log('123');
}
>>123
复制代码
for和while如何选择
break
for(let i = 0; i < 5; i++){
console.log("外面的循环结构" + i);
for(let j = 0; j < 5; j++){
console.log("里面的循环结构-----" + j);
break;
}
}
复制代码
continue
for(let num = 1; num <= 10; num++){
if(num === 1){
continue;
console.log("continue后面的代码"); // 永远执行不到
}
console.log("发射子弹" + num);
复制代码
//循环嵌套规律
// 在循环嵌套中外循环控制的是行数, 内循环控制的是列数
for(let j = 0;j < 3;j++){
for(let i = 0;i < 4;i++){
document.write('*');
}
document.write('<br>');
}
// 规律: 若是尖尖朝下, 那么只须要修改内循环的初始化表达式为外循环初始化表达式的变量便可
for(let i = 0;i < 5;i++){
for(let j = i;j < 5;j++){
document.write('*');
}
document.write('<br>');
}
// 规律: 若是尖尖朝上, 那么只须要修改内循环的条件表达式为外循环初始化表达式的变量便可
for(let i = 0;i < 5;i++){
for(let j = 0;j <= i;j++){
document.write('*');
}
document.write('<br>');
}
复制代码
1.什么是数组?
2.如何建立一个数组?
let 变量名称 = new Array(size);
复制代码
3.如何操做数据
变量名称[索引号] = 须要存储的数据;
复制代码
变量名称[索引号];
复制代码
let arr = new Array(3);
arr[0] = 'zs';
console.log(arr[0]);
复制代码
4.注意点
let arr = new Array(3);
console.log(arr[0]); >>undefined
复制代码
let arr = new Array(3);
console.log(arr[666]); >>undefined
复制代码
let arr = new Array(3);
arr[0] = "lnj";
arr[1] = "zs";
arr[2] = "ls";
arr[3] = "it666";
console.log(arr); >>['lnj','zs','ls','it666']
复制代码
let arr = new Array(4);
arr[0] = 123;
arr[1] = "123";
arr[2] = true;
arr[3] = null;
console.log(arr); >>[123,'123',true,null]
复制代码
和其它编程语言不一样, JavaScript中数组分配的存储空间不必定是连续的
在浏览器中各大浏览器也对数组分配存储空间进行了优化
建立数组的其它方式
let 变量名称 = new Array(size); //建立一个指定大小数组
let 变量名称 = new Array(); //建立一个空数组
let 变量名称 = new Array(data1,data2,...);
//建立一个带数据的数组
复制代码
let 变量名称 = []; //建立一个空数组
let 变量名称 = [data1,data2,...]; //建立一个带数据的数组
复制代码
let arr=['a','b',c];
for(let i=0; i<arr.length; i++){
console.log(arr[i]);
}
复制代码
let [a,b,c] = [1,3,5];
let [a,b,[c,d]] = [1,3,[2,4]];
复制代码
let [a,b] = [1,3,5];
console.log(a);
console.log(b); >>1,3
复制代码
let [a,b,c] = [1];
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c); >>1,undefined,undefined
复制代码
let [a, b = 666, c = 888] = [1];
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c); >>1,666,888
复制代码
let [a, b = 666] = [1, 3, 5];
console.log("a = " + a);
console.log("b = " + b); >>1,3
复制代码
ES6中新增的扩展运算符: ...
let [a, ...b] = [1,3,5];
console.log(a); >>1
console.log(b); >>[3,5]
复制代码
1.查
let arr = ['a','b','c'];
需求: 获取数组中索引为1的那个数据
console.log(arr[1]);
复制代码
2.改
//需求: 将索引为1的数据修改成m
arr[1] = 'm';
console.log(arr);
//需求: 将索引为1的数据修改成d, 索引为2的修改成e
arr.splice(1,2,'d','e');
console.log(arr);
//参数1:从什么位置开始
//参数2:须要替换多少元素
//参数3:新的内容
复制代码
3.增
需求: 要求在数组最后添加一条数据
let res = arr.push('d');
console.log(res); >>4
console.log(arr); >>['a','b','c','d']
复制代码
需求: 要求在数组最前面添加一条数据
let res = arr.unshift('m');
console.log(res); >>4
console.log(arr); >>['a','b','c','m']
复制代码
4.删
需求: 要求删除数组最后一条数据
let res = arr.pop();
console.log(res); >>c
console.log(arr); >>['a','b']
复制代码
需求: 要求删除数组最前面一条数据
let res = arr.shift();
console.log(res); >>a
console.log(arr); >>['b','c']
复制代码
需求: 要求删除数组中索引为1的数据
arr.splice(1,1);
console.log(arr); >>['a','c']
复制代码
1..如何清空数组
let arr = [1, 2, 3, 4, 5];
arr = []; //第一种方法
arr.length = 0; //第二种方法
arr.splice(0, arr.length) //第三种方法
console.log(arr); >>Array(0)
复制代码
2.如何将数组转换为字符串
let str = arr.toString();
console.log(str); >>1,2,3,4,5
console.log(typeof str); >>string
复制代码
3.如何将数组转换成指定格式字符串
let str = arr.join('+');
console.log(str); >>1+2+3+4+5
console.log(typeof str); >>string
复制代码
4.如何将两个数组拼接为一个数组
let arr1 = [1, 3, 5];
let arr2 = [2, 4, 6];
let res = arr1.concat(arr2); //第一种方法
let res = [...arr1, ...arr2]; //第二种方法
console.log(res); >>[1,3,5,2,4,6]
console.log(typeof res); >>object
复制代码
5.如何对数组中的内容进行反转
let res = arr.reverse();
console.log(res); >>[5,4,3,2,1]
console.log(arr); >>[5,4,3,2,1]
复制代码
6.如何截取数组中指定范围内容
let res = arr.slice(1,3);
console.log(res); >>[2,3]
console.log(arr); >>[1,2,3,4,5]
复制代码
7.如何查找元素在数组中的位置
let arr = [1, 2, 3, 4, 5, 3];
let res = arr.indexOf(3); >>2
let res = arr.indexOf(3,4); >>5
let res = arr.lastIndexOf(3,4); >>2
console.log(res);
复制代码
8.如何判断数组中是否包含某个元素
//能够经过indexOf和lastIndexOf的结果, 判断是不是-1便可
let arr = [1, 2, 3, 4, 5];
let res = arr.indexOf(8); >>-1
let res = arr.lastIndexOf(8); >>-1
let res = arr.includes(4); >>true
console.log(res);
复制代码
9.练习
//已知数组[3, 5, -2, 7, 4], 获取数组中的最大值并打印
let arr = [3,5,-2,7,4];
let max = arr[0];
for(let i=1;i<arr.length;i++){
if(arr[1]>max){
max=arr[i];
}
}
console.log(max);
//要求用户输入3个0~9的数, 输出0~9中哪些用户没有输入过
let str = prompt('请输入三个整数,用逗号隔开');
let arr = str.split(',');
//第一种方法
for(let i=0;i<10;i++){
if(arr[0] == i || arr[1] == i || arr[2] == i){
continue;
}
console.log(i);
}
//第二种方法
let res = new Array(10);
for(let i=0;i<arr.length;i++){
let res=arr[i];
res[str]=666;
}
for(let i=0;i<res.length;i++){
if(res[i]===666){
continue;
}
console.log(i);
}
//从接盘接收5个0~9的数字, 排序后输出(数组计数)
let str = prompt("请输入五个整数, 用逗号隔开");
let arr = str.split(",");
let res = new Array(10);
res.fill(0);
for(let i=0;i<res.length;i++){
let str=arr[i];
res[str]=res[str]+1;
}
for(let j=0;j<res[i];j++){
document.write(i);
document.write('<br>');
}
//从接盘接收4个数字, 排序后输出
let str = prompt("请输入五个整数, 用逗号隔开");
let arr = str.split(",");
console.log(arr);
//第一种方法(数组选择)
for(let i=0;i<3;i++){
for(let j=i;j<3;j++){
if(arr[i]>arr[j+1]{
let temp=arr[i];
arr[i]=arr[j+1];
arr[j+1]=temp;
}
}
document.write('<br>');
}
//第二种方法(数组冒泡)
for(let i=0;i<3;i++){
for(let j=0;j<3-i;j++){
if(arr[j]>arr[j+1]){
let temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
console.log(arr);
复制代码
1.什么是二维数组?
let arr=[1,3,5]; //一维数组
let arr=[[1,3],[2,4]]; //二维数组
复制代码
2.如何操做二维数组?
let arr = [[1, 3], [2, 4]];
let arr1 = arr[0]; //获取一维
let ele = arr[0][1]; //获取二维
复制代码
let arr = [[],[]];
arr[0] = [1, 3];
arr[1][0] = 2;
复制代码
let arr = [[1, 3], [2, 4]];
for(let i=0;i<arr.length;i++){
let subArray=arr[i];
for(let j=0;j<subArray.length;j++){
console.log(subArray[j]);
}
}
复制代码
1.什么是函数?
2.函数格式
function 函数名称(形参列表){
被封装的代码;
}
复制代码
3.不使用函数的弊端
4.使用函数的好处
// 定义向左变道的函数
function toLeft(){
console.log('打左转向灯');
console.log("踩刹车");
console.log("向左打方向盘");
console.log("回正方向盘");
}
// 定义向右变道的函数
function toRight(){
console.log("打右转向灯");
console.log("向右打方向盘");
console.log("回正方向盘");
}
// 向左变道
// 如下代码的含义: 找到名称叫作toLeft的函数, 执行这个函数中封装的代码
toLeft();
// 向右变道
toRight();
复制代码
1.书写函数的固定格式
2.给函数起一个有意义的名称
3.肯定函数的形参列表
4.将须要封装的代码拷贝到{}中
5.肯定函数的返回值
function getSum(a,b){
let res=a+b;
return res;
}
let num1=10;
let num2=20;
let result=getSum(num1,num2);
console.log(result); >>30
复制代码
注意点
1.一个函数能够有形参也能够没有形参(零个或多个)
// 没有形参的函数
function say(){
console.log('hello world');
}
say();
// 有形参的函数
function say(name){
console.log('hello'+name);
}
say('lnj');
复制代码
2.一个函数能够有返回值也能够没有返回值
// 没有返回值的函数
function say(){
console.log('hello world');
}
say();
// 有返回值的函数
function getSum(a,b){
return a+b;
}
let res=getSum(10,20);
console.log(res);
复制代码
3.函数没有经过return明确返回值, 默认返回undefined
function say(){
console.log("hello world");
return;
}
let res = say();
console.log(res); >>undefined
复制代码
4.return的做用和break类似, 因此return后面不能编写任何语句(永远执行不到)
function say(){
console.log("hello world");
return;
console.log("return后面的代码");
}
say(); >>hello world
复制代码
5.调用函数时实参的个数和形参的个数能够不相同
6.JavaScript中的函数和数组同样, 都是引用数据类型(对象类型)
let say=function(){
console.log("hello world");
}
say();
复制代码
1.由于console.log();也是经过()来调用的, 因此log也是一个函数
function say(){
console.log('hello world');
}
window.say();
复制代码
2.log函数的特色
console.log(1);
console.log(1,2);
console.log(1,2,3);
复制代码
3.为何log函数能够接收1个或多个参数
4.arguments的做用
//注意点: 每一个函数中都有一个叫作arguments的东东
// arguments实际上是一个伪数组
function getSum(){
let sum=0;
for(let i=0;i<arguments.length;i++){
let num=arguments[i];
sum +=num;
}
return sum;
}
let res=getSum(10,20,30);
console.log(res); >>60
复制代码
let [a, ...b]=[1,3,5]; >>a=1;b=[3,5];
复制代码
let arr1=[1,3,5];
let arr2=[2,4,6];
let arr=[...arr1, ...arr2];
>>let arr=[1,3,5,2,4,6];
复制代码
function getSum(...values){
let sum=0;
for(let i=0;i<values.length;i++){
let num=values[i];
sum +=num;
}
return sum;
}
let res=getSum(10,20,30);
console.log(res); >>60
复制代码
格式: 条件A || 条件B
若是条件A成立, 那么就返回条件A
若是条件A不成立, 不管条件B是否成立, 都会返回条件B
function getSum(a,b){
a = a || "指趣学院";
b = b || "知播渔教育";
console.log(a, b);
}
getSum(123, "abc"); >>指趣学院 知播渔教育
复制代码
function getSum(a='指趣学院',b=getDefault()){
console.log(a,b);
}
getSum();
function getDefault(){
return '李南江'
}
复制代码
let say=function(){
console.log('hello world');
}
function test(fn){ //let fn=say;
fn();
}
test(say); >>hello world
复制代码
function test(){
let say=function(){
console.log('hello world');
}
return say;
}
let fn=test(); //let fn=say;
fn(); >>hello world
复制代码
1.什么是匿名函数?
// 有名称的函数
function say(){
console.log('hello lnj');
}
// 匿名函数
function(){
console.log('hello lnj');
}
复制代码
2.匿名函数的注意点
3.匿名函数的应用场景
function test(fn){ //let fn=say;
fn();
}
test(function(){
console.log('hello world');
});
复制代码
function test(){
return function(){
console.log('hello world');
};
}
let fn=test();
fn();
复制代码
(function(){
console.log('hello it666');
})();
复制代码
1.什么是箭头函数?
2.在ES6以前如何定义函数
function 函数名称(形参列表){
须要封装的代码;
}
let 函数名称 = function(形参列表){
须要封装的代码;
}
复制代码
3.从ES6开始如何定义函数
let 函数名称=(形参列表)=>{
须要封装的代码;
}
复制代码
4.箭头函数的注意点
let say = name => {
console.log("hello " + name);
}
say("it666"); >>hello it666
复制代码
let say = name => console.log("hello " + name);
say("it666"); >>hello it666
复制代码
1.什么是递归函数?
2.递归函数的注意点
需求: 要求用户输入密码, 判断输入密码是否正确(假设正确密码是123456),若是正确, 输出"欢迎回来",若是不正确, 要求用户从新输入
function login(){
let pwd=prompt('请输入密码');
if(pwd != '123456'){
login();
}
alert('欢迎回来');
}
login();
复制代码
在JavaScript中{}外面的做用域, 咱们称之为全局做用域
在JavaScript中函数后面{}中的的做用域, 咱们称之为"局部做用域"
在ES6中只要{}没有和函数结合在一块儿, 那么应该"块级做用域"
{
// 块级做用域
}
if(false){
// 块级做用域
}
while(false){
// 块级做用域
}
for(;;){
// 块级做用域
}
do{
// 块级做用域
}while(false);
switch(){
// 块级做用域
}
function say(){
// 局部做用域
}
复制代码
块级做用域和局部做用域区别
{
var num=123; // 全局变量
let num=123; // 局部变量
}
复制代码
function test(){
var value=666; // 局部变量
let value=666; // 局部变量
value=666; // 全局变量
}
复制代码
不管是在块级做用域仍是在局部做用域, 省略变量前面的let或者var就会变成一个全局变量
var | let | |
---|---|---|
{}外 | 全局变量 | 全局变量 |
{}内 | 全局变量 | 局部变量 |
函数内 | 局部变量 | 局部变量 |
注意点: 初学者在研究"做用域链"的时候最好将ES6以前和ES6分开研究
1.ES6以前
须要明确:
做用域链
查找规则
// 全局做用域 / 0级做用域
// var num = 123;
function demo(){
// 1级做用域
// var num = 456;
function test(){
// 2级做用域
// var num = 789;
console.log(num);
}
test();
}
demo(); >>789
复制代码
2.ES6
// 全局做用域 / 0级做用域
// let num = 123;
{
// 1级做用域
function test(){
// 2级做用域
// let num = 789;
console.log(num);
}
test();
}
复制代码
1.什么是预解析?
2.预解析规则
3.注意点
// 预解析以前
console.log(num); //undefined
var num = 123;
// 预解析以后
var num;
console.log(num);
num = 123;
// 不会预解析以前
console.log(num); // 报错
let num = 456;
// ES6以前定义函数的格式
console.log(say);
say();
// ES6以前的这种定义函数的格式, 是会被预解析的, 因此能够提早调用
function say(){
console.log("hello it666");
}
// 预解析以后的代码
function say(){
console.log("hello it666");
}
say();
console.log(say);
say(); // say is not a function
// 若是将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析
var say=function(){
console.log("hello itzb");
}
var say; //undefined
say();
var say=function(){
console.log("hello itzb");
}
// ES6定义函数的格式
say(); // say is not defined
let say=()=>{
console.log("hello itzb");
}
复制代码
//在ES6以前没有块级做用域, 而且没有将这两个函数定义到其它的函数中,因此这两个函数应该属于全局做用域
if(true){
function demo(){
console.log("hello demo1111111111");
}
}else{
function demo(){
console.log("hello demo2222222222");
}
}
demo();
function demo(){
console.log("hello demo1111111111");
}
function demo(){
console.log("hello demo2222222222");
}
if(true){}else{}
demo();
复制代码
console.log(value); // 会输出函数的定义
var value = 123;
function value(){
console.log("fn value");
}
console.log(value); // 会输出123
function value(){
console.log("fn value");
}
console.log(value);
var value;
value = 123;
console.log(value);
复制代码
1.面向过程和面向对象的区别
//买电脑
1.面向过程
了解电脑——了解本身的需求——对比参数——去电脑城——微信付钱——买回电脑——被坑
2.面向对象
找班长——描述需求——班长把电脑买回来
复制代码
2.JavaScript中提供了一个默认的类Object, 咱们能够经过这个类来建立对象
3.因为咱们是使用系统默认的类建立的对象, 因此系统不知道咱们想要什么属性和行为, 因此咱们必须手动的添加咱们想要的属性和行为
4.如何给一个对象添加属性
5.如何给一个对象添加行为
// 建立对象的第一种方式
let obj = new Object();
obj.name = "lnj";
obj.age = 33;
obj.say=function(){
console.log("hello world");
}
console.log(obj.name);
console.log(obj.age);
obj.say();
// 建立对象的第二种方式
let obj = {}; // let obj = new Object();
obj.name = "lnj";
obj.age = 33;
obj.say=function(){
console.log("hello world");
}
console.log(obj.name);
console.log(obj.age);
obj.say();
// 建立对象的第三种方式
// 注意点: 属性名称和取值之间用冒号隔开, 属性和属性之间用逗号隔开
let obj={
name: "lnj",
age: 33,
say:function(){
console.log("hello world");
}
}
console.log(obj.name);
console.log(obj.age);
obj.say();
复制代码
1.什么是函数?
2.什么是方法?
3.函数和方法的区别
4.不管是函数仍是方法, 内部都有一个叫作this的东东
function demo(){
console.log(this);
}
demo(); //window.demo();
let obj={
name: "lnj",
test:function(){
console.log(this);
}
}
test(); //obj.test();
复制代码
1.什么是工厂函数?
function createPerson(myName,myAge){
let obj = new Object();
obj.name = myName;
obj.age = myAge;
obj.say=function(){
console.log("hello world");
}
return obj;
}
let obj1 = createPerson("lnj", 34);
let obj2 = createPerson("zs", 44);
console.log(obj1);
console.log(obj2);
复制代码
1.什么是构造函数
2.构造函数和工厂函数的区别
function Person(myName,MyAge){
// let obj = new Object(); // 系统自动添加的
// let this = obj; // 系统自动添加的
this.name = myName;
this.age = myAge;
this.say=function(){
console.log("hello world");
}
// return this; // 系统自动添加的
}
let obj1 = new Person("lnj", 34);
let obj2 = new Person("zs", 44);
console.log(obj1);
console.log(obj2);
//当咱们new Person("lnj", 34);系统作了什么事情
1)会在构造函数中自动建立一个对象
2)会自动将刚才建立的对象赋值给this
3)会在构造函数的最后自动添加return this;
复制代码
function Person(myName, myAge) {
// let obj = new Object(); // 系统自动添加的
// let this = obj; // 系统自动添加的
this.name = myName;
this.age = myAge;
this.say = function () {
// 方法中的this谁调用就是谁, 因此当前是obj1调用, 因此当前的this就是obj1
// console.log("hello world");
console.log(this.name, this.age);
}
// return this; // 系统自动添加的
}
let obj1 = new Person("lnj", 34);
// console.log(obj1.name);
// console.log(obj1.age);
obj1.say();
function Person(myName, myAge) {
// let obj = new Object(); // 系统自动添加的
// let this = obj; // 系统自动添加的
this.name = myName;
this.age = myAge;
this.say = function () {
console.log("hello world");
}
// return this; // 系统自动添加的
}
let obj1 = new Person("lnj", 34);
let obj2 = new Person("zs", 44);
// 因为两个对象中的say方法的实现都是同样的, 可是保存到了不一样的存储空间中,因此有性能问题
console.log(obj1.say === obj2.say); // false
function demo() {
console.log("demo");
}
// 经过三个等号来判断两个函数名称, 表示判断两个函数是否都存储在同一块内存中
console.log(demo === demo); // true
复制代码
4.构造函数优化
function mySay(){
console.log("hello world");
}
function Person(myName,Myage){
// let obj = new Object(); // 系统自动添加的
// let this = obj; // 系统自动添加的
this.name = myName;
this.age = myAge;
this.say = mySay;
// return this; // 系统自动添加的
}
let obj1 = new Person("lnj", 34);
let obj2 = new Person("zs", 44);
console.log(obj1.say === obj2.say); // true
当前这种方式解决以后存在的弊端:
1)阅读性下降了
2)污染了全局的命名空间
复制代码
let fns={
test:function(){
console.log("test");
}
}
console.log(fns.test === fns.test); // true
// 因为test函数都是属于同一个对象, 因此返回true
let fns = {
mySay: function () {
console.log("hello world");
}
}
function Person(myName, myAge) {
// let obj = new Object(); // 系统自动添加的
// let this = obj; // 系统自动添加的
this.name = myName;
this.age = myAge;
this.say = fns.mySay;
// return this; // 系统自动添加的
}
let obj1 = new Person("lnj", 34);
let obj2 = new Person("zs", 44);
console.log(obj1.say === obj2.say); // true
复制代码
function Person(myName, myAge) {
// let obj = new Object(); // 系统自动添加的
// let this = obj; // 系统自动添加的
this.name = myName;
this.age = myAge;
// this.say = fns.mySay;
// return this; // 系统自动添加的
}
Person.prototype = {
say: function () {
console.log("hello world");
}
}
let obj1 = new Person("lnj", 34);
obj1.say();
let obj2 = new Person("zs", 44);
obj2.say();
console.log(obj1.say === obj2.say); // true
复制代码
1.特色
2.应用场景
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
this.currentType = "构造函数中的type";
this.say = function () {
console.log("构造函数中的say");
}
}
Person.prototype = {
currentType: "人",
say: function () {
console.log("hello world");
}
}
let obj1 = new Person("lnj", 34);
obj1.say(); >>构造函数中的say
console.log(obj1.currentType); >>构造函数中的type
let obj2 = new Person("zs", 44);
obj2.say(); >>构造函数中的say
console.log(obj2.currentType); >>构造函数中的type
复制代码
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
}
let obj1 = new Person("lnj", 34);
console.log(Person.prototype); >>object
console.log(Person.prototype.constructor); >>Person函数
console.log(obj1.__proto__); >>object
复制代码
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
}
let obj1 = new Person("lnj", 34);
console.log(Function === Function.prototype.constructor); // true
console.log(Person.__proto__ === Function.prototype); // true
复制代码
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
}
let obj1 = new Person("lnj", 34);
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype); // true
console.log(Object.prototype.constructor === Object); // true
console.log(Object.prototype.__proto__); // null
复制代码
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
// this.currentType = "构造函数中的type";
// this.say = function () {
// console.log("构造函数中的say");
// }
}
Person.prototype = {
// 注意点: 为了避免破坏原有的关系, 在给prototype赋值的时候, 须要在自定义的对象中手动的添加constructor属性, 手动的指定须要指向谁
constructor: Person,
// currentType: "人",
// say: function () {
// console.log("hello world");
// }
}
let obj1 = new Person("lnj", 34);
// obj1.say();
console.log(obj1.currentType); >>报错
// console.log(Person.prototype.constructor);
复制代码
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
}
Person.prototype = {
constructor: Person,
currentType: "人",
say: function () {
console.log("hello world");
}
}
let obj = new Person("lnj", 34);
obj.currentType = "新设置的值";
console.log(obj.currentType); // 新设置的值
console.log(obj.__proto__.currentType); // "人"
复制代码
function Person() {
this.name = "lnj";
let age = 34;
this.setAge = function (myAge) {
if (myAge >= 0) {
age = myAge;
}
}
this.getAge = function () {
return age;
}
this.say = function () {
console.log("hello world");
}
}
let obj = new Person();
// 1.操做的是私有属性(局部变量)
obj.setAge(-3);
console.log(obj.getAge());
// 2.操做的是公有属性
obj.age = -3;
console.log(obj.age);
复制代码
function Person() {
this.name = "lnj";
this.say = function () {
console.log("hello world");
}
}
// 经过构造函数建立的对象, 咱们称之为"实例对象"
let obj = new Person();
console.log(obj.name);
obj.say();
obj.age = 34;
console.log(obj.age);
obj.eat = function () {
console.log("eat");
}
obj.eat();
// 构造函数也是一个"对象", 因此咱们也能够给构造函数动态添加属性和方法
Person.num = 666;
Person.run = function () {
console.log("run");
}
console.log(Person.num);
Person.run();
复制代码
1.this是什么?
2.这三个方法的做用是什么?
3.三者区别
let obj={
name:'zs';
}
function test(a,b){
console.log(a,b);
console.log(this);
}
//修改属性
let fn=test.bind(obj,10,20);
fn(); >>10 20 {name:'zs'}
test.call(obj,10,20); >>10 20 {name:'zs'}
test.apply(obj,[10,20]); >>10 20 {name:'zs'}
//修改方法
function Person(){
this.name='lnj';
this.say=function(){
console.log(this);
}
}
let p=new Person();
let fn=p.say.bind(obj);
fn(); >>{name:'zs'}
p.say.call(obj); >>{name:'zs'}
p.say.apply(obj); >>{name:'zs'}
复制代码
1.封装性
function Person() {
this.name = "lnj";
// this.age = 34;
let age = 34;
this.setAge = function (myAge) {
if(myAge >= 0){
age = myAge;
}
}
this.getAge = function () {
return age;
}
this.say = function () {
console.log("hello world");
}
// 因为构造函数也是一个函数, 因此也会开启一个新的做用域
// 因此在构造函数中经过var/let定义的变量也是局部变量
// 因此在构造函数中定义的函数也是局部函数
var num = 123;
let value = 456;
function test() {
console.log("test");
}
}
let obj = new Person();
// 结论: 默认状况下对象的属性和方法都是公开的, 只要拿到对象就能够操做对象的属性和方法
// console.log(obj.name);
// obj.age = -3;
// console.log(obj.age);
// obj.say();
复制代码
2.继承性
简介
继承方式一
function Person() {
this.name = null;
this.age = 0;
this.say = function () {
console.log(this.name, this.age);
}
}
let per = new Person();
per.name = "lnj";
per.age = 34;
per.say();
function Student() {
// this.name = null;
// this.age = 0;
// this.say = function () {
// console.log(this.name, this.age);
// }
this.score = 0;
this.study = function () {
console.log("day day up");
}
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
//弊端
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
this.say = function () {
console.log(this.name, this.age);
}
}
function Student(myName, myAge, myScore) {
this.score = myScore;
this.study = function () {
console.log("day day up");
}
}
复制代码
function Person(myName, myAge) {
// let per = new Object();
// let this = per;
// this = stu;
this.name = myName; // stu.name = myName;
this.age = myAge; // stu.age = myAge;
this.say = function () { // stu.say = function () {}
console.log(this.name, this.age);
}
// return this;
}
function Student(myName,myAge,myScore){
//let stu=new Object();
//let this=stu;
Person.call(this,myName,myAge);
this.score=myScore;
this.study=function(){
console.log('day day up');
}
return this;
}
let stu=new Student('ww',19,99);
console.log(stu.score); >>99
stu.say(); >>19,99
stu.study(); >>day day up
复制代码
function Person(myName, myAge) {
// let per = new Object();
// let this = per;
// this = stu;
this.name = myName; // stu.name = myName;
this.age = myAge; // stu.age = myAge;
// return this;
}
Person.prototype.say = function () {
console.log(this.name, this.age);
}
function Student(myName, myAge, myScore) {
Person.call(this, myName, myAge);
this.score = myScore;
this.study = function () {
console.log("day day up");
}
}
// 注意点: 要想使用Person原型对象中的属性和方法, 那么就必须将Student的原型对象改成Person的原型对象才能够
Student.prototype=Person.prototype;
Student.prototype.constructor=Student;
let stu = new Student("ww", 19, 99);
console.log(stu.score); >>99
stu.say(); >>ww,19
stu.study(); >>day day up
复制代码
function Person(myName, myAge) {
// let per = new Object();
// let this = per;
// this = stu;
this.name = myName; // stu.name = myName;
this.age = myAge; // stu.age = myAge;
// return this;
}
Person.prototype.say = function () {
console.log(this.name, this.age);
}
function Student(myName, myAge, myScore) {
Person.call(this, myName, myAge);
this.score = myScore;
this.study = function () {
console.log("day day up");
}
}
Student.prototype=new Person();
Student.prototype.constructor=Student;
Student.prototype.run=function(){
console.log('run');
}
let per=new Person();
per.run(); >>报错
复制代码
3.多态性
什么是强类型语言, 什么是是弱类型语言
什么是多态?
多态在编程语言中的体现
//强类型语言(继承+多态)
function Animal(myName) {
this.name = myName;
this.eat = function () {
console.log(this.name + " 动物吃东西");
}
}
function Dog() {
Animal.call(this, myName);
this.eat = function () {
console.log(" 狗吃东西");
}
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
function Cat() {
Animal.call(this, myName);
this.eat = function () {
console.log(" 猫吃东西");
}
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
function feed(Animal animal) {
animal.eat(); // 狗吃东西
}
//弱类型语言
function Dog() {
//Animal.call(this, myName);
this.eat = function () {
console.log(" 狗吃东西");
}
}
function Cat() {
//Animal.call(this, myName);
this.eat = function () {
console.log(" 猫吃东西");
}
}
function feed(animal){
animal.eat();
}
let dog = new Dog();
feed(dog); >>狗吃东西
let cat = new Cat();
feed(cat); >>猫吃东西
复制代码
1.在ES6以前若是定义一个类?
function Person(myName, myAge) {
// 实例属性
// this.name = "lnj";
// this.age = 34;
this.name = myName;
this.age = myAge;
// 实例方法
this.say = function () {
console.log(this.name, this.age);
}
// 静态属性
Person.num = 666;
// 静态方法
Person.run = function () {
console.log("run");
}
}
// let p = new Person();
let p = new Person("zs", 18);
p.say();
console.log(Person.num);
Person.run();
复制代码
class Person{
//实例属性
constructor(myName,myAge){
this.name=myName;
this.age=myAge;
this.hi=function(){
console.log('hi');
}
}
// 如下定义"实例属性"的方式并非ES6正式版标准中的写法, 大部分的浏览器不支持
// name = "lnj";
// age = 34;
//实例方法(会自动添加到原型位置中,若是想要该方法放在原函数里,那就放在constructor里)
say(){
console.log(this.name,this.age);
}
//静态属性
// 如下定义"静态属性"的方式并非ES6正式版标准中的写法, 大部分的浏览器不支持
static num=666;
//静态方法
static run(){
console.log('run');
}
}
let p=new Person('zs',18);
p.say(); >>zs,18
console.log(Person.rum); >>666
Person.run(); >>run
复制代码
//构造函数
//第一种方法:
Person.prototype.type='人';
Person.prototype.say=function(){
console.log(this.name,this.age);
};
//第二种方法:
Person.prototype={
constructor:Person,
type:'人',
say:function(){
console.log(this.name,this.age);
}
};
//ES6类
Person.prototype.type='人';
Person.prototype.say=function(){
console.log(this.name,this.age);
};
复制代码
function Person(myName, myAge) {
this.name = myName;
this.age = myAge;
}
Person.prototype.say = function () {
console.log(this.name, this.age);
}
function Student(myName, myAge, myScore) {
// 1.在子类中经过call/apply方法借助父类的构造函数
Person.call(this, myName, myAge);
this.score = myScore;
this.study = function () {
console.log("day day up");
}
}
// 2.将子类的原型对象设置为父类的实例对象
Student.prototype = new Person();
Student.prototype.constructor = Student;
let stu = new Student("zs", 18, 99);
stu.say();
复制代码
class Person{
constructor(myName, myAge){
// this = stu;
this.name = myName; // stu.name = myName;
this.age = myAge; // stu.age = myAge;
}
say(){
console.log(this.name, this.age);
}
}
// 如下代码的含义: 告诉浏览器未来Student这个类须要继承于Person这个类
class Student extends Person{
constructor(myName,myAge,myScore){
super(myName,myAge); //至关于Person.call(this,myName,myAge);
this.score=myScore;
}
study(){
console.log('day day up');
}
}
let stu=new Student('zs',18,98);
stu.say();
复制代码
let obj = new Object();
console.log(typeof obj); // object
let arr = new Array();
console.log(arr.constructor.name); //Array
function Person() {
// let obj = new Object();
// let this = obj;
this.name = "lnj";
this.age = 34;
this.say = function () {
console.log(this.name, this.age);
}
// return this;
}
let p = new Person();
// console.log(typeof p); // object
console.log(p.constructor.name); // Person
复制代码
1.什么是instanceof关键字?
2.instanceof注意点
class Person{
name = "lnj";
}
let p = new Person();
console.log(p instanceof Person); >>true
class Cat{
name = "mm";
}
let c = new Cat();
console.log(c instanceof Person); // false
function Person(myName) {
this.name = myName;
}
function Student(myName, myScore) {
Person.call(this, myName);
this.score = myScore;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
let stu = new Student();
console.log(stu instanceof Person); // true
复制代码
1.什么是isPrototypeOf属性
2.isPrototypeOf注意点
class Person{
name = "lnj";
}
let p = new Person();
console.log(Person.prototype.isPrototypeOf(p)); // true
class Cat{
name = "mm";
}
console.log(Cat.prototype.isPrototypeOf(p)); // false
function Person(myName) {
this.name = myName;
}
function Student(myName, myScore) {
Person.call(this, myName);
this.score = myScore;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
let stu = new Student();
console.log(Person.prototype.isPrototypeOf(stu)); // true
复制代码
// 需求: 判断某一个对象是否拥有某一个属性
class Person{
name=null;
age=0;
}
Person.prototype.height=0;
let p = new Person();
// in的特色: 只要类中或者原型对象中有, 就会返回true
console.log("name" in p); // true
console.log("height" in p); // true
// 需求: 判断某一个对象自身是否拥有某一个属性
// hasOwnProperty特色: 只会去类中查找有没有, 不会去原型对象中查找
console.log(p.hasOwnProperty("name")); // true
console.log(p.hasOwnProperty("height")); // false
复制代码
1.增长(C)
class Person{}
let p=new Person();
//增长属性
p.name='gh';
p['name']='hj';
//增长方法
p.say=function(){
console.log('hello');
}
p['say']=function(){
console.log('hello');
}
复制代码
2.删除(R)
//删除属性
delete p.name;
delete p['name'];
//删除方法
delete p.say;
delete p['say'];
复制代码
3.修改(U)
p.name = "lnj";
p["name"] = "ww";
console.log(p.name);
p.say = function(){
console.log("hi");
}
p["say"] = function(){
console.log("hi");
}
p.say();
复制代码
4.查询(D)
console.log(p.name);
console.log(p["name"]);
p.say();
复制代码
1.在JavaScript中对象和数组同样是能够遍历的
2.什么是对象的遍历?
3.如何遍历一个对象?
//如下代码的含义: 将指定对象中全部的属性和方法的名称取出来了依次的赋值给key这个变量
for(let key in obj){}
// ES6
class Person{
constructor(myName, myAge){
this.name = myName;
this.age = myAge;
}
// 注意点: ES6定义类的格式, 会将方法默认放到原型对象中,遍历取不出来
say(){
console.log(this.name, this.age);
}
}
let p=new Person("LNJ", 34);
for(let key in p){
console.log(key);
}
>>lnj 34
复制代码
function Person(myName, myAge){
this.name = myName;
this.age = myAge;
this.say = function(){
console.log(this.name, this.age);
}
}
let p = new Person("LNJ", 34);
for(let key in p){
if(p[key] instanceof Function){
continue; //判断是否是函数
}
// console.log(key); // name / age / say
// 注意点: 如下代码的含义取出p对象中名称叫作当前遍历到的名称的属性或者方法的取值
console.log(p[key]); // p["name"] / p["age"] / p["say"]
// 注意点: 如下代码的含义取出p对象中名称叫作key的属性的取值
// console.log(p.key); // undefined
}
复制代码
1.注意点
2.在数组的解构赋值中, 等号左边的格式必须和等号右边的格式如出一辙, 才能彻底解构
let [a, b, c] = [1, 3, 5];
console.log(a, b, c); // 1 3 5
复制代码
3.在数组的解构赋值中, 两边的个数能够不同
let [a, b] = [1, 3, 5];
console.log(a, b); // 1 3
let [a, b, c] = [1, 3];
console.log(a, b, c); // 1 3 undefined
复制代码
4.在数组的解构赋值中,若是右边少于左边, 咱们能够给左边指定默认值
let [a, b, c = 666] = [1, 3];
console.log(a, b, c); // 1 3 666
复制代码
5.练习
let obj={
name:'lk',
age:35
}
let {name,age}=obj;
let {name,age}={name:'lk',age:35};
console.log(name,age); >>lk,35
let {name}={name:'lk',age:35};
console.log(name,age); >>lk
let {name, age, height} = {name: "lnj",age: 34};
console.log(name, age, height); >>lnj,34,undefined
let {name, age, height = 1.80} = {name: "lnj",age: 34};
console.log(name, age, height); >>lnj,34,1.80
//注意点: 在对象解构赋值中, 左边的变量名称必须和对象的属性名称一致, 才能解构出数据
let {age} = {name: "lnj",age: 34};
console.log(age); // 34
let {a, b} = {name: "lnj",age: 34};
console.log(a, b); // undefined undefined
复制代码
6.应用场景
//数组应用
let arr=[1,3];
function sum([a,b]){
return a+b;
}
let res=sum(arr);
console.log(res); >>4
//对象应用
let obj={
name:'lk',
age:15
}
function say({name,age}){
console.log(name,age);
}
say(obj); >>lk,15
复制代码
1.什么是深拷贝什么是浅拷贝?
//深拷贝
let num1 = 123;
let num2 = num1;
num2 = 666; // 修改形变量的值
console.log(num1);
console.log(num2);
//浅拷贝
class Person{
name = "lnj";
age = 34;
}
let p1 = new Person();
let p2 = p1; //传递内存地址
p2.name = "zs"; // 修改变量的值
console.log(p1.name); >>zs
console.log(p2.name); >>zs
复制代码
2.对象深拷贝
class Person{
name = "lnj";
age = 34;
}
let p1 = new Person();
let p2 = new Object();
//第一种方式
p2.name = p1.name;
p2.age = p1.age;
p2.name = "zs";
//第二种方式
for(let key in p1){
p2[key]=p1[key];
}
p2.name='zs';
//第三种方式
// assign方法能够将第二个参数的对象的属性和方法拷贝到第一个参数的对象中
Object.assign(p2, p1);
p2.name = "zs";
console.log(p1.name);
console.log(p2.name);
// 注意点: 只有被拷贝对象中全部属性都是基本数据类型, 以上代码才是深拷贝
复制代码
class Person{
name = "lnj";
cat = {
age : 3
};
scores = [1, 3, 5];
}
let p1 = new Person(); >>3
let p2 = new Object(); >>666
depCopy(p2,p1);
function depCopy(target,source){
// 1.经过遍历拿到source中全部的属性
for(let key in source){
// 2.取出当前遍历到的属性对应的取值
let sourceValue=source[key];
// 3.判断当前的取值是不是引用数据类型
if(sourceValue instanceof Object){
let subTarget new sourceValue.constructor;
target[key]=subTarget;
depCopy(subTarget,sourceValue);
}else{
target[key]=sourceValue;
}
}
}
复制代码
3.调试技巧
F12—Source:能够断点看函数的执行过程
1.遍历数组
// 需求: 要求遍历数组
// 1.利用传统循环来遍历数组
let arr = [1, 3, 5, 7, 9];
for(let i=0;i<arr.length;i++){
console.log(arr[i]);
}
//2.利用forin循环来遍历数组
for(let key in arr){
console.log(arr[key]);
}
function Person() {
this.name = "lnj";
this.age = 34;
this.score = 99;
}
// 注意点: 对象中的属性是无序的
// forin循环是专门用于遍历对象的, 可是对象的属性是无序的, 因此forin循环就是专门用于遍历无序的东西的, 因此不推荐使用forin循环来遍历数组
let p = new Person();
console.log(p);
//3.利用ES6中推出的for of循环来遍历数组
for(let value of arr){
console.log(value);
}
//4.还能够利用Array对象的forEach方法来遍历数组
arr.forEach(function(currentValue,currentIndex,curentArray){
console.log(currentValue);
});
//forEach实现原理
Array.prototype.myForEach=function(fn){
for(let i=0;i<this.length;i++){
fn(this[i],i,this);
}
};
arr.myForEach(function(currentValue,currentIndex,currentArray){
console.log(currentValue,currentIndex,currentArray);
});
复制代码
2.数组查找
let arr = [3, 2, 6, 7, 6];
// 从左往右查找, 找到返回索引, 找不到返回-1
let index1 = arr.indexOf(6);
console.log(index1); // 2
// 从右至左查找, 找到返回索引, 找不到返回-1
let index2 = arr.lastIndexOf(6);
console.log(index2); // 4
// 从左往右查找, 找到返回true, 找不到返回false
let result = arr.includes(6);
console.log(result); // true
//数组的findIndex方法
let index = arr.findIndex(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
// if(currentValue === 6){
if(currentValue === 10){
return true;
}
});
console.log(index); >>-1
// findIndex实现
Array.prototype.myFindIndex = function (fn) {
for(let i = 0; i < this.length; i++){
let result = fn(this[i], i, this);
if(result){
return i;
}
}
return -1;
}
//数组的find方法
let value = arr.find(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
// if(currentValue === 6){
if(currentValue === 10){
return true;
}
});
console.log(value); >>undefined
// findIndex实现
Array.prototype.myFind = function (fn) {
for(let i = 0; i < this.length; i++){
let result = fn(this[i], i, this);
if(result !== undefined){
return result;
}
}
return undefined;
}
复制代码
3.数组过滤和映射
let arr = [1, 2, 3, 4, 5];
let newArray=arr.filter(function(currentValue,currentIndex,currentArray){
if(currentValue % 2 === 0){
return true;
}
});
console.log(newArray); >>[2,4]
// filter实现
Array.prototype.myFilter=function(fn){
let newArray=[];
for(let i=0;i<this.length;i++){
let result=fn(this[i],i,this);
if(result){
newArray.push(this[i]);
}
}
return newArray;
}
复制代码
let newArray=arr.map(function(currentValue,currentIndex,currentArray){
if(currentValue % 2 === 0){
return currentValue;
}
});
console.log(newArray); >>[undefined,2,undefined,4,undefined]
// map实现
Array.prototype.myMap=function(fn){
let newArray=new Array(this.length);
newArray.fill(undefined);
for(let i=0;i<this.length;i++){
let result=fn(this[i],i,this);
if(result !== undefined){
newArray[i]=result;
}
}
return newArray;
}
复制代码
let arr = [1, 2, 3, 4, 5];
// 需求: 遍历的同时删除数组中全部元素
//第一种方法
let len=arr.length;
for(let i=len-1;i>=0;i--){
arr.splice(i,1);
}
//第二种方法
// 注意点: 经过delete来删除数组中的元素, 数组的length属性不会发生变化
for(let i=0;i<arr.length;i++){
console.log(arr.length); >>5
delete arr[i];
}
console.log(arr); >>[1, 2, 3, 4, 5]
复制代码
let arr = ["c", "a", "b"];
//arr.sort();
arr.sort(function(a,b){
if(a>b){
return -1;
}else if(a<b){
return 1;
}else{
return 0;
}
});
console.log(arr);
//规律: 若是数组中的元素是数值类型,若是须要升序排序, 那么就返回a - b;若是须要降序排序, 那么就返回b - a;
let arr = [3, 4, 2, 5, 1];
// arr.sort();
arr.sort(function(a,b){
return a-b;
});
console.log(arr);
let arr = ["1234", "21", "54321", "123", "6"];
arr.sort(function(str1,str2){
return str2.length-str1.length;
});
console.log(arr);
let students = [
{name: "zs", age: 34},
{name: "ls", age: 18},
{name: "ww", age: 22},
{name: "mm", age: 28},
];
students.sort(function (o1, o2) {
// return o1.age - o2.age;
return o2.age - o1.age;
});
console.log(students);
复制代码
// 1.获取字符串长度 .length
let str='abcd';
console.log(str.length); >>4
// 2.获取某个字符 [索引] / charAt
let str='abcd';
//第一种方法,仅高级浏览器支持
let ch=str[1];
//第二种方法,没有兼容性问题
let ch=str.charAt(1);
console.log(ch); >>a
// 3.字符串查找 indexOf / lastIndexOf / includes
let str = "vavcd";
let index=str.indexOf('v'); >>0
let index=str.lastIndexOf('v'); >>2
console.log(index);
let result=str.includes('p');
console.log(result); >>false
// 4.拼接字符串 concat / +
let str1 = "www";
let str2 = "it666";
let str=str1+str2; //推荐
let str=str1.concat(str2);
console.log(str);
// 5.截取子串 slice / substring / substr
let str = "abcdef";
let subStr=str.slice(1,3); >>bc
let subStr=str.substring(1,3); >>bc
let subStr=str.substr(1,3); >>bcd
console.log(subStr);
// 6.字符串切割
let arr = [1, 3, 5];
let str=arr.join('-');
console.log(str); >>1-3-5
let str = "1-3-5";
let arr=str.split('-');
console.log(arr); >>['1','3','5']
// 7.判断是否以指定字符串开头 ES6
let str = "www.it666.com";
let result=str.startsWith('www');
console.log(result); >>true
// 8.判断是否以指定字符串结尾 ES6
let str = "lnj.jpg";
let result=str.endsWith('png');
console.log(result); >>true
// 9.字符串模板 ES6
//常规方法
let str = "";
let str = '';
//新方法:反引号
let str=`www.it666.com`;
console.log(str); >>www.it666.com
console.log(typeof str); >>string
let str = "<ul>\n" +
" <li>我是第1个li</li>\n" +
" <li>我是第2个li</li>\n" +
" <li>我是第3个li</li>\n" +
"</ul>";
//上面的字符串每行都要有加号,换成反引号就不用加号了
let str = `<ul> <li>我是第1个li</li> <li>我是第2个li</li> <li>我是第3个li</li> </ul>`;
let name = "lnj";
let age = 34;
let str=`个人名字是${name},个人年龄是${age}`;
console.log(str); >>个人名字是lnj,个人年龄是34
复制代码
1.有哪些基本数据类型?
2.经过字面量建立的基本数据类型的数据都是常量
3.常量的特色和注意点
4.基本类型特色
5.对象类型的特色
6.之前之因此可以访问基本数据类型的属性和方法, 是由于在运行的时候系统自动将基本数据类型包装成了对象类型
//修改常量
let str = "abc";
str[1] = "m";
console.log(str); // abc
let newStr=str.replace('b','m');
console.log(newStr); // amc
//修改拼接
let str1 = "www";
let str2 = "it666";
let str3 = str1 + str2;
console.log(str1); //www
console.log(str2); //it666
console.log(str3); //wwwit666
//基本类型没有属性和方法
let str = "lnj";
str.age = 34;
str.say=function(){
console.log('hello');
}
console.log(str.age); // undefined
str.say(); // str.say is not a function
//系统自动将基本数据类型包装成了对象类型
let str = "www.it666.com";
// let str = new String(str); //隐藏过程
console.log(str.length);
str.split(".");
复制代码
JavaScript中提供三种自带的对象, 分别是"本地对象"/"内置对象"/"宿主对象"
什么是宿主?
1.本地对象
2.内置对象
3.宿主对象
4.自定义对象
let num = 3.9;
let value=Math.floor(num);
console.log(value); //3
复制代码
let num = 3.9;
let value=Math.ceil(num);
console.log(value); //4
复制代码
let num = 3.5;
let value=Math.round(num);
console.log(value); //4.0
复制代码
let num = -3;
let value=Math.abs(num);
console.log(value); //3
复制代码
let value = Math.random();
console.log(value);
// 需求: 要求生成一个1~10的随机数
function getRandomIntInclusive(min,max){
min=Math.ceil(min);
max=Math.floor(max);
return Math.floor(Math.random()*(max-min+1))+min;
} //含最大值,含最小值,从MDN复制过来
let value=getRandomIntInclusive(1,10);
console.log(value);
复制代码