JavaScript基础语法 demo3

JavaScript基础语法

这篇笔记主要讲了JavaScript函数,变量作用域,预解析,对象,内部对象以及两种数据类型
这篇笔记有很多JavaScript的特性,所以可以认真看下
这篇笔记是初学者写下的笔记,如有错误,欢迎前来指正

JavaScript函数

  • 函数:重复使用某些代码,实现代码复用
  • 函数命名仍然是小驼峰命名
  • 函数可以调用另一个函数 (可以先使用后定义)
  • 函数里面还可以嵌套函数

JavaScript函数使用

  • 代码示例:
// 声明
function 函数名(形参1, 形参2) {
    // 函数体
    return 参数;
}
var 接收变量 = 函数名(实参1, 实参2); // 调用
  • 注意:不需要声明形参,可以直接写一个参数名

  • 形参的个数和实参不匹配也可以:

    • 实参个数 > 形参个数:只读取形参的个数
    • 实参个数 < 形参个数:没有值的形参默认为undefined
  • return语句之后的代码不会被执行

  • return只能返回一个值,返回多个值以最后一个值为准

  • 想要返回多个值,可以使用数组作为返回值

  • 函数没有return的话,返回的值是undefined

arguments使用

  • arguments:所有函数都内置了一个arguments对象,存储了所有实参
  • 可以用于所有的函数,包括对象内的函数
  • 代码示例:
function test() {
    console.log(arguments);
    // 输出[1,2,3]
}
test(1,2,3);
  • arguments展示的是伪数组,所以可以遍历
    • 可以使用length属性
    • 可以用下标索引
    • 不同点:没有数组的 push 和 pop 方法
arguments使用案例
  • 求未知个数的数组里的最大值
function getMax() {
    var max = 0;
    for (var i = 0; i < arguments.length; i++) {
        if (max < arguments[i]) {
            max = arguments[i];
        }
    }
    return max;
}
console.log(getMax(1,2,3,4,7,3,4,5));
// 输出7

函数声明两种方式

  • 直接声明 (function方法):
function fn() {
}
fn();
  • 函数表达式 (匿名函数):
var 变量名 = function(){};
// 调用
变量名();

变量作用域

  • es6 版本之前:全局变量,局部变量

    • 全局变量:作用于 script 标签之间或者一个js文件
    • 局部变量:在函数内部声明的变量
  • 注意:全局变量和局部变量名字可以相同,不会起冲突

  • 如果在同一个作用域下名字相同,后面的值会把前面的值覆盖

  • 特例!

function fun() {
    var num1 = 10;
    num2 = 20;
}
console.log(num1);
// 报错,变量未定义
console.log(num2);
// 可以直接输出
  • 注意:在函数内部没有声明直接赋值的变量也属于全局变量
  • 函数的形参也属于局部变量

块级作用域 (新属性)

  • 现阶段没有块级作用域
  • 在一个花括号里面的作用域
  • 注意!和其他语言不同,JavaScript在if,for里面定义的变量都是可以全局使用的,只有函数里声明的变量才是局部变量

作用域链

  • 内部函数可以访问外部函数
  • 代码示例:
var num = 10;
function fn() {
    var num = 20;
    function fun() {
        console.log(num);
        // 问题:这时输出哪个num值?
    }
}
// 输出 20
  • 这时输出离变量最近的声明 (就近原则)

JavaScript预解析

  • 情景一:
console.log(num);
var num = 10;
// 输出结果 undefined
  • 情景二:
fn();
function fn() {
    console.log('test');
}
// fn();
// 无论fn在定义函数前面还是定义函数后面,都可以正常输出 test
  • 情景三:
fn(); // 报错
var fn = function() {
    console.log('test');
}
// 这里只提升了var fn;
// js以为他是个变量,所以会报错
  • 运行js代码时分为两步:1.预解析 2.代码执行

    • 预解析:会把所有的 var 和 function 提升到作用域的最前面
    • 代码执行:按照代码执行的顺序执行
  • 注意!预解析只提升变量声明,不提升变量赋值

  • 函数提升的时候把 function 声明的函数整个提升到最前面 (所以即使先使用后声明也可以正常运行)

预解析实例

var num = 10;
fun();
function fun() {
    console.log(num);
    var num = 20;
}
// 输出结果 undefined
  • 解析:最外层function会提升到最前面,然后fun()调用这个函数的时候,函数预解析:
function fun() {
    var num;
    console.log(num);
    num = 20;
}
  • 所以输出的是undefined

  • 特例!var a = b = c = 9 相当于 var a = 9; b = 9; c = 9;

  • 所以这里的 b 和 c 直接赋值,相当于全局变量

JavaScript对象

  • 对象是指一个具体的东西,而不是泛指

创建对象的三种方式 (自定义对象)

  • 在对象里面声明的叫属性或方法

java里面的函数都是写在类内的,所以叫方法

直接创建对象
  • 代码示例:
var obj = {}; // 创建一个空对象
var obj2 = { // 这里是直接新建了一个对象叫obj2
    name : '菜鸟小铭', // 注意!这里是逗号
    age : 18 ,
    hello: function() {
        console.log('Hello');
    }
}
// 调用对象
console.log(obj2.name);
// 另一种方法
console.log(obj2['age']);
// 调用方法
obj2.hello();
  • 注意!里面用的是冒号,多个属性用逗号隔开
  • 方法后面跟的是匿名函数
利用new object创建对象
  • 代码示例:
var obj = new Object(); // 创建一个空对象
// 然后追加属性和方法
obj.name = '代码小铭';
obj.age = 18;
obj.Hello = function() {
    console.log('Hello');
}
// 调用和上面的一样
console.log(obj.name);
console.log(obj['age']);
obj.hello();
  • 注意!Object必须要大写
利用构造函数创建对象
  • 最接近其他语言的方法 (类似于类)
  • 代码示例:
function Student(name) {
    this.name = name;
    this.study = function(active) {
        console.log(active));
    }
}
// 声明 声明时需要加new!
var xiaoming = new Student('菜鸟小铭');
// 调用对象
console.log(xiaoming.name);
xiaoming.study('study');
  • 注意!构造函数首字母大写
  • 构造函数不需要return就可以返回一个对象
  • 属性和方法前面必须加this
new的作用
  1. new之后创建了一个空的对象
  2. 里面的this指针指向空对象
  3. 然后执行属性和方法
  4. 然后返回这个对象

遍历对象属性 (for…in循环)

  • for in 循环可以用于数组和对象
  • 代码示例:
var obj = {
    name : '代码小铭',
    age : 18,
    gender : man,
}

for (var k in obj) {
    console.log(k); // 得到的是属性名
    console.log(obj[k]); // 得到的是属性值
}
  • 小知识:for…in里面的变量喜欢用 k 或者 key
  • 也可以遍历出方法

JavaScript内置对象

  • 内置对象:js语言自带的对象

  • 文档网站推荐:MDN网站

Math对象
  • Math对象不是构造函数,所以不需要new,直接使用就可以
  • 代码示例:
console.log(Math.PI);
// 输出3.14……
  • 里面有max方法
    • 参数不限个数
    • 如果有不是数据的参数,则会返回NaN
    • 如果没有参数返回-Infinity
绝对值和取整
  • 代码示例:
// 绝对值
console.log(Math.abs(-1));
// 输出1
console.log(Math.abs('-1'));
// 同样输出1 (隐式转换)

// 向下取整
console.log(Math.floor(1.9));
// 输出1

// 向上取整
console.log(Math.cell(1.1));
// 输出2

// 四舍五入
console.log(Math.round(1.5));
// 输出2

// 四舍五入特例 (.5的时候往大了取)
console.log(Math.round(-1.5));
// 输出-1
随机数 (random)
  • random 返回 0 到 1 之间的小数 (可以取到0,取不到1)
  • 代码示例:
console.log(Math.random());

// 两个数之间的随机整数,包括这两个数
function getRandomIntInclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
Date对象
  • 时间开始于 1970 年 1 月 1 日
  • Date是构造函数,需要 new 一个日期对象
  • 代码示例:
var date = new Date();

// 如果没有参数,返回当前系统时间
console.log(date);
// 输出 Tue Mar 10 2020 20:43:20 GMT+0800 (中国标准时间)

// 数字型
var date1 = new Date(2019,10,01);
console.log(date1);
// 输出2019年11月1日 (比实际月份大 1 月)
// 因为月份是从0月开始算的

// 字符串型
var date2 = new Date('2019-10-1 20:03:20');
// 正常输出
日期格式化
  • 推荐看MDN里的 get 开头的属性
  • 以 dateFullYear,getMonth 为例
var date = new Date();
console.log(date.getFullYear());
// 输出2020
console.log(date.getMonth());
// 输出结果比实际少 1 月 (月份是从零开始算的)
  • 注意:周日返回为 0 (可以使用数组来更改)
  • 想要分钟等出现 02 这样,三元运算符判断,字符串连接
时间戳 (距离1970年的毫秒数)
  • valueOf(),getTime(),+new Date(),Date.now()四种方法
  • 应用:程序运行时间
  • 代码示例:
var date =new Date();
console.log(date.valueOf());
console.log(date.getTime());

// 简单写法 (最常用)
var date1 = +new Date();
console.log(date1);

// H5新增方法
console.log(Date.noe());
时间戳示例:倒计时
  • 不能直接用时分秒直接减(会出现负数),但是可以用时间戳可以直接减
  • 代码实例:
function countDown(times) {
    var nowTime = +new Date();
    var inputTime = +new Date(time);
    var times = inputTime - nowTime;
    times /= 1000;
    var dd = parseInt(times / 60 / 60 / 24);
    var hh = parseInt(times / 60 / 60 % 24);
    var mm = parseInt(times / 60 % 60);
    var ss = parseInt(times % 60);
}
数组对象 (Array)
  • new 新建数组详解:
var arr = new Array(2);
// 里面的2代表数组长度为2
var arr = new Array(2 , 3);
// 新建一个 [2,3] 的数组
检测是否为数组
  • 用 instanceof 运算符来检测
  • 代码示例:
var srr = [];
console.log(arr instanceof Array);
// 输出结果 true
console.log(Math instanceof Object);
// 输出结果 true
  • instanceof详解
  • 感觉是判断这个对象是否是这个构造函数的对象 (因为数组的类型其实也是对象)

  • 用 Array.isArray(参数) 来判断 (H5新增方法)
  • 代码示例:
var arr = [];
console.log(Array.isArray(arr));
// 输出结果 true
  • 和 instanceof 的区别:
    • isArray能检测到iframes
添加和删除数组元素
方法名说明返回值
push(参数)在末尾添加一个或多个元素返回新数组的长度
unshift(参数)在开头加入一个或多个元素返回新数组的长度
pop()删除数组最后一个元素返回删除元素的值
shift()删除数组第一个元素返回删除元素的值
.splice(index,howmany,item)删除数组指定元素返回删除元素的值
slice(begin,end)截取从begin到end返回新数组
  • 详解 .splice 使用方法:

    • index:删除哪一位的元素
    • howmany:删除这位的元素多少个
    • item:替换这个元素的值
  • 代码示例:

var arr = new Array(1,2,3);
console.log(arr.push(4,'tom'));
// 输出5
console.log(arr);
// 输出[1,2,3,4,"tom"]

var arr = new Array(1,2,3);
console.log(arr.unshift(0));
// 输出4
console.log(arr);
// 输出[0,1,2,3]

var arr = new Array(1,2,3);
console.log(arr.pop());
// 输出3 (被删除的那个元素)
console.log(arr);
// 输出[1,2]

var arr = new Array(1,2,3);
console.log(arr.shift());
// 输出1 (被删除的那个元素)
console.log(arr);
// 输出[2,3]

var arr = [1,2,3,4,5]
arr.splice(2,2,0);
console.log(arr);
// 输出[1,2,0,0,5]
数组排序
方法名说明
reverse()颠倒数组中元素的顺序
sort()对数组元素进行排序 (冒泡排序)
  • 返回值是更新后的数组
  • 代码示例:
var arr = [1,2,3];
arr.reverse();
console.log(arr);
// 输出[3,2,1]

var arr = [7,3,4,6,8,9,1];
arr.sort();
console.log(arr);
// 输出[1,3,4,6,7,8,9]
  • sort排序是有缺陷的,他会先判断十位再判断个位
  • 就会出现以下情况:
var arr = [13,4,45,7,77,1];
arr.sort();
console.log(arr);
// 输出 [1,13,4,45,7,77]
  • 解决方法:
var arr = [13,4,45,7,77,1];
arr.sort(function(a,b) {
    return a - b; // 升序排列
})
console.log(arr);
// 输出[1,4,7,13,45,77]
  • 这里用a - b是升序排列,b - a就是降序排列
数组索引
方法名说明
indexOf()数组查找指定元素的第一个索引
lastIndexOf()数组查找指定元素最后一个索引
  • 返回的是元素的下标
  • 如果不存在则返回 -1
  • 代码示例:
var arr = [1,2,3,4,5,2];
console.log(arr.indexOf(2));
// 返回1
console.log(arr.lastIndexOf(2));
// 返回5
数组索引实例:数组去重
  • 我的解题思路:如果前面索引和后面索引的值相等,那么直接跳过;如果前面的索引和后面的索引不等,则去除后面索引到的元素,并且key-1 (为了防止出现多个重复)
  • 代码示例:
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'a', 'c', 'n'];
for (var key = 0; key < arr.length; key++) {
    if (arr.indexOf(arr[key]) == arr.lastIndexOf(arr[key])) {
        continue;
    }
    if (arr[key] == arr[arr.lastIndexOf(arr[key])]) {
        arr.splice(arr.lastIndexOf(arr[key]), 1);
        key--;
    }
}
console.log(arr);
  • 老师的解法:遍历旧数组,然后查询新数组是否有重复,如果没有重复则添加
var arr = ['c','a','z','a','x','a','x','a','c','n'];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
    if (newArr.indexOf(arr[i]) == -1) {
        newArr.push(arr[i]);
    }
}
console.log(newArr);

老师的方法比我的方法简单一万倍

数组转化为字符串
方法名说明
toString()数组转化为字符串,逗号分隔
join(‘分隔符’)分隔符分割开 (什么都不写默认是逗号)
  • 返回值是转换好的字符串
  • 代码示例:
var arr = [1,2,3];
console.log(arr.toString());
// 输出1,2,3
console.log(arr.join(''));
// 输出123
字符串对象
  • 字符串是简单数据类型,但是有属性和方法
  • 基本包装类型:把简单数据类型包装成复杂数据类型 (String, Number, Boolean)
  • 过程:
var str = '菜鸟小铭';
var temp = new String('菜鸟小铭');
str = temp;
temp = null; // 销毁中间变量
字符串的不可变
  • 用户声明一个字符串并且赋初值后,再拿另一个值去覆盖这个变量,初始的赋值并没有被销毁,而只是变量名指向了另一个值 (地址改变)

  • 不可变的体现:

var str = '';
for (var i = 0; i < 10000000; i++) {
    str += i;
}
console.log(str);
  • 根据chrome的任务管理器来看,循环一千万次需要内存629.34MB内存 (如果电脑内存不是特别大不建议尝试)
  • 所以不要随意拼接字符串
在字符串里面查找字符
方法名说明
indexOf(‘要查找的字符’,开始的位置)从前往后找,只找第一个
lastIndexOf(‘要查找的字符’,开始的位置)从后往前找,只找第一个匹配的
  • 返回在字符串里的位置,找不到返回 -1
  • 代码示例:
var str = 'JavaScript!';
console.log(str.indexOf('S'));
// 返回4
var str = 'assa';
console.log(str.indexOf('a',1));
// 返回3
// lastIndexOf同理
根据位置返回字符
方法名说明
charAt(index)返回指定位置的字符
charCodeAt(index)获取指定位置字符的ASSII码
str[index]获取指定位置字符 (H5新增)
  • 代码示例:
var str = 'JavaScript!';
console.log(charAt(5));
// 输出c
console.log(charCodeAt(5));
// 输出99
cosnle.log(str[5]);
// 输出c
  • 可以使用对象名[‘属性’]的方法来获取对象里面的属性及属性的值
字符串的操作
方法名说明
concat(str1,str2)连接 数组/字符串,等效于 +
substr(start,length)截取字符串 从 start 处开始截取,截取 length 这么长 重要
replace(‘被替换的字符’,‘替换为的字符’)替换字符 (只替换第一个)
split(‘分隔符’)字符转换为数组 (和join类似)
  • 代码示例:
var str = 'abca';
console.log(str.replace('a','z'));
// 输出 zbca

var str = 'a,b,c';
console.log(str.split(','))
// 输出 [a,b,c]

JavaScript数据类型

简单数据类型

  • 包括:Number,String,Bollean,undefined,null

  • null 是一个对象

    • 应用:有个变量以后打算存对象,可以用 null占位
  • 在栈中储存数据

  • 简单数据类型传参

    • 直接把栈里面的值覆盖掉

复杂数据类型

  • 用 new 创建的类型

  • 包括Object,Array

  • 在堆中储存:在栈中存放地址,地址指向堆,在堆里面存放数据

  • 复杂数据类型传参

    • 先找到放在栈中的变量名,取出里面的地址,找到地址指向的堆,再修改里面的变量
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值