JavaScript 语法基础 Part.3

9 作用域

(1) 概述

<1> 全局作用域:作用于所有代码执行的环境(整个script标签内部)或者一个独立的js文件。
<2> 局部作用域(函数作用域):作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。
<3> 块级作用域:块作用域由 { } 包括。在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在本 if 语句、本循环语句中使用。
//Js中没有块级作用域(在ES6之前)。

(2) 对变量根据作用域分类

<1> 全局变量

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
//即在script标签或js文件内、在函数外定义的变量。
全局变量在代码的任何位置都可以使用。
在全局作用域下 var 声明的变量是全局变量。
***特殊情况下,*在函数内*不声明var的变量也是全局变量(不建议使用)。

<2> 局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)。
//即在函数内定义的变量。
局部变量只能在该函数内部使用。
在函数内部 var 声明的变量是局部变量。
函数的形参实际上就是局部变量。

<3> 全局变量和局部变量的区别

全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存。
局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间。

(3) 作用域链

<1> 只要是代码,就至少有一个作用域,即全局作用域。
<2> 如果函数中还有函数,那么在这个局部作用域中就又可以诞生一个局部作用域。
//全局作用域、外部函数的局部作用域、内部函数的局部作用域就构成了作用域链。
<3> 根据*在内部函数可以访问外部函数变量的这种机制*,用链式查找决定哪些数据能被内部函数访问,就称为作用域链。
//若一个变量在分别在全局作用域、外部函数的局部作用域、内部函数的局部作用域中定义,采取*就近原则*的方式来查找变量最终的值。

 

10 预解析

(1) 概述

//是 在变量声明之前访问变量的值是undefined,在函数声明之前就可以调用函数 的原因。
JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。

<1> 预解析

在当前作用域下, JS 代码执行之前,浏览器会进行变量预解析(变量提升)和函数预解析(函数提升)。
//即把带有var和function声明的变量在内存中进行提前声明或者定义。
//预解析只会发生在var定义的变量和function上。
变量预解析(变量提升):变量的声明会被提升到*当前*作用域的最上面,变量的赋值*不会提升*。
函数预解析(函数提升):函数的声明会被提升到*当前*作用域的最上面,但是*不会调用*函数。

<2> 代码执行

从上到下执行JS语句,包括赋值语句。

(2) 案例

<1> 案例1:

var num = 10;
function fn(){
    console.log(num);
    var num = 20;
    console.log(num);
} 
fn();

相当于:

var num;
function fn(){
var num;
    console.log(num); //undefine
    num = 20;
    console.log(num); //20
}
fn();

<2> 案例2:

f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
  var a = b = c = 9;
  console.log(a);
  console.log(b);
  console.log(c);
}

相当于:

function f1() {
  var a;
  a = 9;
  b = 9; //函数内未声明,为全局变量。
  c = 9; //函数内未声明,为全局变量。
  console.log(a); //9
  console.log(b); //9
  console.log(c); //9
}
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //报错,因为全局作用域内没有变量a。


11 对象

(1) 创建对象

<1> 利用字面量创建对象 

对象字面量:就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法。{ } 里面采取键值对的形式表示。
//键:相当于属性名。
//值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型、函数类型等)。

var obj = {
    name:'李华',
    age:18,
    sex:'男',
    sayHi:function(){ //方法也可以理解为一个属性。
        alert('Hi!');
    }
};

<2> 利用 new Object 创建对象 

//Object():第一个字母大写。
var obj = new Object(); //创建一个空对象。
obj.name = '李华'; //为空对象添加属性与方法。
obj.age = 18;
obj.sex = '男';
obj.sayHi = function(){
    alert('Hi!');
}

<3> 利用构造函数创建对象 

//JS中的构造方法相当于Java中的类。
是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

//1 构造函数约定首字母大写。
function Person(name, age, sex) {
//2 函数内的属性和方法前面需要添加this,表示当前对象的属性和方法。
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.sayHi = function() {
    alert('Hi!');
    }
    //3 构造函数中不需要return返回结果。
}
//4 当我们创建对象的时候,必须用new来调用构造函数。
var obj = new Person('LiHua', 18, '男');

(2) new关键字执行过程

<1> 在内存中创建一个新的空对象。
<2> 让 this 指向这个新的对象。
<3> 执行构造函数里面的代码,给这个新对象添加属性和方法。
<4> 返回这个新对象(所以构造函数里面不需要return)。

(3) 调用对象

<1> 调用属性:对象.属性名
<2> 调用属性:对象['属性名'] //注意方括号里面的属性必须加引号。
<3> 调用方法:对象.方法名() //注意这个方法名字后面一定加括号。

(4) 遍历对象属性

for (var key in 对象名) {
    alert(key); //这里输出的是属性名。
   alert(对象名[key]); //这里输出的是属性值。
   //只能使用此方式调用属性,不能使用 对象.属性名 方式调用属性。
}

(5) 变量、属性、函数、方法总结

<1> 变量:单独声明赋值,单独存在。
<2> 属性:对象里面的变量称为属性,使用“对象.属性名”的方式就可以调用,不需要声明,用来描述该对象的特征。
<3> 函数:单独存在的,通过“函数名()”的方式就可以调用。
<4> 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用,方法用来描述该对象的行为和功能。 


12 内置对象

(1) 概述

<1> JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象。
<2> 内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)。
<3> 内置对象最大的优点就是帮助我们快速开发,JavaScript提供了多个内置对象:Math、 Date 、Array、String等。

(2) 数学对象

//不是构造函数,相当于静态类,使用:Math.方法名/属性名

<1> 概述

Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值等)可以使用Math中的成员。
Math.PI //圆周率
Math.floor() //向下取整
Math.ceil() //向上取整
Math.round() //四舍五入,就近取整,特别注意负数
Math.abs() //绝对值
Math.max()/Math.min() //求最大和最小值
//上面的方法必须带括号

<2> 随机数方法 random()

<2.1> random()方法可以随机返回一个小数,其取值范围是[0,1),左闭右开0<=x<1。
<2.2> 得到一个两数之间的随机整数,包括两个数在内

function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min; 
}

(3) 日期对象

//是一个构造方法,相当于类,使用:var date = new Date();

<1> 概述

Date 对象和 Math 对象不一样,他是一个构造函数,所以我们需要实例化(new)后才能使用。
Date 实例用来处理日期和时间。

<2> Date()方法的使用

<2.1> 获取当前时间必须实例化
var date = new Date();
<2.2> Date() 构造函数的参数
如果Date()不写参数,就返回当前时间。
如果Date()里面写参数,就返回括号里面输入的时间。
//例如日期格式字符串为'2019-5-1',可以写成new Date('2019-5-1')或者new Date('2019/5/1')

<3> 日期格式化

//若要获得某种格式的日期,需要获取日期指定的部分,所以我们要手动的得到这种格式。
获取当年 getFulYear()
获取当月(0-11) getMonth() //返回的月份小一个月,使用时应 getMonth()+1
获取当日 getDate()
获取星期几(周日为0) getDay()
获取当前小时 getHours()
获取当前分钟 getMinutes()
获取当前秒钟 getSeconds()

<4> 获取日期的总的毫秒形式

//也称时间戳。
//Date 对象是基于1970年1月1日(世界标准时间)起的毫秒数。
<4.1> 第一种方式:
var now = new Date(); //实例化Date对象
console.log(date.valueOf(日期)/date.valueOf()) //用于获取对象的原始值
console.log(date.getTime(日期)/date.getTime())//用于获取对象的原始值
//两个方法都可以获取日期的总的毫秒形式。
<4.2> 第二种方式:
var now = + new Date(日期)/Date();
<4.3> 第三种方式(HTML5中提供的方法,有兼容性问题):
var now = Date.now(日期)/Date.now();

<5> 案例

将时间格式化为xx年xx月xx日 星期xx

function getTime(){
    var time = new Date();
    var year = time.getFulYear();
    var month = time.getMonth() + 1;
    var date = time.getDate();
    var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']
    var day = time.getDay();
    retrun '今天是:' + year + '年' +  month + '月' + date +'日 ' + arr[day];
}
console.log(getTime());

将时间格式化为xx时xx分xx秒(自动补0)

function getTime(){
    var time = new Date();
    var h = time.getHours();
    h = h < 10 ? '0' + h : h;//若不足两位,自动补0。
    var m = time.getMinutes();
    m = m < 10 ? '0' + m : m;//若不足两位,自动补0。
    var s = time.getSeconds();
    s = s < 10 ? '0' + s : s;//若不足两位,自动补0。
    return h + ':' + m + ':' + s;
}
console.log(getTime());

倒计时

function downTime(time){
    var nowTime = + new Date(); //获取当前日期的总的毫秒形式
    var inputTime = + new Date(time); //获取截至日期的总的毫秒形式
    var times = (inputTime - nowTime) / 1000; //获取相差时间的总秒数
    var d = parselnt(times / 60 / 60 / 24); //将秒转化为天
    d = d < 10 ? '0' + d : d;
    var h = parselnt(times / 60 / 60 % 24); //将秒转化为时
    h = h < 10 ? '0' + h : h;
    var m = parselnt(times / 60 % 60); //将秒转化为分
    m = m < 10 ? '0' + m : m;
    var s = parselnt(times % 60); //将秒转化为秒
    s = s < 10 ? '0' + s : s;
    return d + ':' + h + ':' + m + ':' + s;
}
alert(downTime('2024-8-15 18:00:00'));

(4) 数组对象

<1> 数组对象的创建

见 7 数组

<2> 检测是否为数组

instanceof 运算符,可以判断一个对象是否属于某种类型。
//例:console.log(obj instanceof Array);
Array.isArray()用于判断一个对象是否为数组,isArray()是HTML5中提供的方法。
//例:console.log(Array.isArray(obj));

<3> 添加删除数组元素的方法

//使用:数组名.方法名();
push(参数1,参数2,参数3...):末尾添加一个或多个元素,修改原数组,并返回新的长度。
unshift(参数1,参数2,参数3...):向数组的开头添加一个或更多元素,注意修改原数组,并返回新的长度。
pop():删除数组最后一个元素,把数组长度减1,无参数,修改原数组,返回它删除的元素的值。
shift():删除数组的第一个元素,数组长度减1无参数,修改原数组,返回它删除的元素的值。

<4> 数组排序

//以下两个方法直接改变原数组,不必创建变量接受新数组。
reverse():颠倒数组中元素的顺序,无参数,该方法会改变原来的数组,返回新数组。
sort():对数组的元素进行排序,该方法会改变原来的数组,返回新数组。

<5> 数组索引

indexOf():数组中查找给定元素的第一个索引,如果存在返回素引号如果不存在,则返回-1。
lastIndexOf():在数组中的最后一个的索引,如果存在返回索引号如果不存在,则返回-1。
数组去重案例:

function unique(arr){
    var newArr = [];
    for(var i = 0;i < arr.length;i++){
        if(newArr.indexOf(arr[i]) === -1){
            newArr.push(arr[i]);
        }
    }
    return newArr;
}
var arr = [1,1,2,5,1,5,7];
unique(arr);

<6> 数组转换为字符串

toString():返回一个字符串,把数组转换成字符串,逗号分隔每一项。
join('分隔符'):返回一个字符串,方法用于把数组中的所有元素转换为一个字符串。

<7> 截取数组

slice():数组截取 slice(begin,end),返回被截取项目的新数组。
splice():数组删除splice (第几个开始,要删除个数),返回被删除项目的新数组注意,这个会影响原数组。

(5) 字符串对象

<1> 字符串的不可变

指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。

<2> 根据字符返回位置

indexof(要查找的字符,开始的位置):返回指定内容在元字符串中的位置,如果找不到就返回-1,开始的位置是index索引号。
lastindexof():从后往前找,只找第一个匹配的。

<3> 根据位置返回字符

charAt(index):返回指定位置的字符(index字符串的素引号)
charCodeAt(index):获取指定位置处字符的ASCI码(index索引号)
str[index]:获取指定位置处字符,HTML5,IE8+支持,和 charAt()等效

<4> 字符串操作方法

concat(str1,str2,str3..):concat()方法用于连接两个或多个字符串。拼接字符串,等效于+,+更常用。
substr(startlength):从start(索引号)位置开始,length取的个数。:切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。
slice(start,end):从start位置开始,截取到end位置,end取不到(两个参数都是索引号)。
substring(start,end):从start位置开始,截取到end位置,end取不到基本和slice相同但是不接受负值。
replace(被替换的字符,要替换为的字符):在字符串中用一些字符替换另一些字符。
//只会替换字符串中第一个出现的字符。
若要替换全部

while(str.indexOf(被替换的字符) !== -1){
    str = str.replace(被替换的字符,要替换为的字符);
}

split('分隔符'):将字符串切分为数组。在切分完毕之后,返回的是一个新数组。

posted @ 2023-05-10 17:20  10kcheung  阅读(25)  评论(0)    收藏  举报