0


JavaScript入门到精通(四)连载

入门JavaScript

    对于一个真正有所追求的人来说,生命的每个时刻都应该是年轻的。人生从来没有来不及,只要你肯,便有未来。

    相信来到第四篇的你对JS也有了初步了解,志坚者,功名之柱也。而今天的任务便是搞懂JS中的 预解析、作用域、对象三个目标。知足知不足,有为有不为。加油~

1.预解析

1.1 由来

   JavaScript代码是由浏览器中的JavaScript解释器来执行的,JavaScript解释器在运行JavaScript代码的时候分为两步:预解析和代码执行

预解析:JS引擎会把JS里面所有的 var 还有 function 提升到当前作用域的最前面

代码执行:按照代码书写的顺序从上往下执行

                                                                      涉及作用域接下来会讲,别急接着往下看~~~

1.2 步骤

   预解析分为 变量预解析 (变量提升) 和 函数预解析 (函数提升)

变量提升:就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作

函数提升:就是把所有的函数声明提升到当前作用域最前面 不调用函数

1.3 案例说明(由浅入深~~~)

案例1

如下代码所示,正常我们先声明变量,然后执行语句,两者颠倒,得出的结果如图所示:

console.log(num); //undefined
var num = 10;

没有输出我们要的结果,也没有报错的原因是由于JS解释器的预解析,相当于执行了以下代码

var num;
console.log(num);
num = 10;

经历预解析,变量提到最前面不进行赋值操作,而代码又从上往下执行,输出的只能是undefined

案例2

正常函数调用,调用函数放在函数声明前面是可以运行的,但函数表达式不行,这次我们以函数表达式声明函数方式举例,代码运行结果如下所示

func();//建议:调用函数必须写在函数表达式的下面,这次以举例为例说明原因
var func = function (){ 
    console.log('张小凡');
}

代码报错的原因是相当于执行了以下代码,声明一个变量没有赋值,又调用了这个变量+();是肯定报错的。代码如下。

var func;
func();
func = function (){
    console.log('张小凡');
}

案例3

经过上面两个案例说明应该了解了变量提升和函数提升,现在将两者柔和一起来试试看~~~

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

观察上面代码,根据步骤一步一步来,知道浏览器解释器是怎么执行这段代码的。

var num;
function fun(){ //函数内部也是要执行预解析的
    var num; //因为就近原则,不会去找全局作用域里面声明的num = 10;所以undefined
    console.log(num);
    num = 20;
}
num = 10;
fun();

案例4

在用案例巩固一下~~ ,加深自己是意识。请看下面代码

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 = b = c = 9;
    // var a = b = c = 9;   相当于 var a = 9; b = 9; c = 9; b和c 直接赋值 没有var声明 当全局变量看
    // 集体声明 var a =9,b = 9,c = 9;
    console.log(a);
    console.log(b);
    console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a); //属于局部变量, 报错

调用了f1();函数,又console.log()三个数,本来能输出六个数字,但因为最后一个 console.log(a);中的a属于局部变量,访问不了所以报错信息里面提示 a is not defined 原因找到。

2.JS作用域

2.1 定义

JavaScript作用域:就是代码名字(变量) 在某个范围内起作用和效果 目的:提高程序的可靠性以及减少命名冲突。

2.2 作用域分类

全局作用域:整个script标签或者是一个单独的js文件

局部作用域:(函数作用域)在函数内部就是局部作用域 只在函数内起作用和效果。

2.3 变量作用域(根据作用域的不同将变量分为全局变量和局部变量)

全局变量:在全局作用域下的变量,在全局下都可以使用; 如果在函数内部,没有声明直接赋值的变量也属于全局变量。

局部变量:在函数作用域下的变量,函数的形参也可以看做是局部变量

从执行效率上看两者的区别:

全局变量只有在浏览器关闭的时候才会销毁,比较占内存资源;局部变量当我们程序执行完毕就会销毁,比较节约内存资源。

2.4 作用域链

内部函数访问外部函数的变量,采用的是链式查找的方式决定哪个值 这种结构我们称为作用域链 使用的是就近原则。

function fun1 () {//外部函数
    var num = 1;
    function fun2 () {//内部函数
        console.log(num);
    }
    fun2();
}
var num = 2;
fun1();

显而易见,由就近原则可知,结果为 1,接下来再看一段代码~~~

var a = 1;
function fn1 () {
    var a = 2; 
    var b = '22'; 
    fn2();
    function fn2 () {
        var a = 3;
        fn3();
        function fn3 () {
            var a = 4;
            console.log(a); // a的值?
            console.log(b); // b的值?
        }
    }
}
fn1();

采用就近原则很快得到答案,看看和你猜的一不一样~

3. 对象

谈到对象,就要涉及了许多方面的内容了,知识量有点大,现在平静一下~,耐心的看下去。

3.1 定义

在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。简而言之:对象是由属性和方法组成。目的:使JS中的对象表达结构更清晰,更强大。

属性:事物的特征,在对象中用属性来表示

方法:事物的行为,在对象中用方法来表示

3.2 创建对象的三种方式

3.2.1 利用字面量创建对象

注意点:1.属性和方法采取键值对的方式 键 属性名;值 属性值 2.多个属性和方法中间逗号隔开 3.方法冒号跟的是一个匿名函数

// var obj = {}; 创建了一个空的对象
var obj = {
    name: '张小凡', //属性区
    age: '18',
    sex: '男',
    say: function () {
        console.log('hello world');
    }
}
// 调用对象属性的方法1:采取对象名.属性名
console.log(obj.name);
// 调用对象属性的方法2:采取对象名['属性名']
console.log(obj['age']);
// 调用对象的方法 say 对象名.方法名()
obj.say();

3.2.2 利用 new Object 创建对象

注意点:采用等号赋值方法 添加对象的属性和方法、每个属性和方法之间用 分号结束

var obj = new Object();
obj.name = '张小凡'; //追加属性
obj.age = 18;
obj.sex = '男';
obj.say = function () { //追加方法
    console.log('hello world');
}

3.2.3 构造函数创建对象

注意点:1.构造函数泛指某一大类 类似于 Java 语言里卖弄的 类 2.特点:把对象里面一些相同的属性和方法抽取出来封装(封装的不是普通代码而是对象)到函数里面,这样避免了很多的属性和方法的大量重复

//构造函数的语法格式
//this总是指向函数的直接调用者(而非间接调用者); 如果有new关键字,this指向new出来的那个对象
function 构造函数名 () {
    this.属性 = 值; 
    this.方法 = function () { }
}
new 构造函数名();

案例:

function Family (name,age,sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.doing = function(result){
        console.log(result);
    }
}
var boy = new Family('张小凡',18,'男');
console.log(boy.name);
console.log(boy['sex']);
boy.result('我在打游戏~')

var girl = new Family('张晓樊',18,'女');
console.log(girl.name);
console.log(girl.sex);
girl.result('我在追剧~')

细节:1、构造函数首字母要大写、构造函数不需要return就可以返回结果、调用构造函数必须使用 new、只要使用new 构造函数名 就相当于创建了一个对象。2、我们利用构造函数创建对象的过程我们称为对象的实例化。3、new 构造函数可以在内存中创建一个空的对象 函数里面的this都会指向这个空对象,执行构造函数里面的代码 给这个空对象添加对象和方法并返回这个新对象

3.3 遍历对象

简言之:for in 遍历我们的对象。

// 格式
for(变量 in 对象){

}

案例:

// 案例
var obj = {
    name:'张小凡',
    age:18,
    sex:'男'
}
for(var key in obj){ //for in 里面的变量我们喜欢写 k 或者 key
    console.log(key); //i 变量输出 得到的是 属性名
    console.log(obj[key]); //obj[i]得到的是属性值
}

3.4 内置对象

定义:指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常见的或是最基本而必要的功能。内置对象的最大优点就是帮助我们快速开发 JS提供多个内置对象:Math、Date等

3.4.1 Math是数学对象 不是一个构造函数,所以我们不需要new来调用 而是直接使用里面的属性和方法即可。

console.log(Math.PI); //一个属性 圆周率
console.log(Math.max(1,45,42));  //45
console.log(Math.max(1,'张小凡')); //NaN
console.log(Math.max()); // -Infinity 负的无穷大

利用对象封装自己的数学对象

var myMath = {
    PI:3.141592653,
    max:function(){
        var max = arguments[0];
        for(var i = 1;i < arguments.length;i++){
            if(arguments[i]>max){
                max = arguments[i];
            }
        }
        return max;
    },
    min:function(){
        var min = arguments[0];
        for(var i = 1;i < arguments.length;i++){
            if(arguments[i]<min){
                min = arguments[i];
            }
        }
        return min;
    },
}
console.log(myMath.PI);
console.log(myMath.max(1,5,8));
console.log(myMath.min(1,5,8));

3.4.2 绝对值方法

console.log(Math.abs(1)); //1
console.log(Math.abs(-1)); //1
console.log(Math.abs('1')); // 隐式转换 会把字符串型 -1 转换为数字型 1
console.log(Math.abs('张小凡')); //NaN

3.4.3 三个取整方法

// (1) Math.floor()  地板 向下取整 往最小取值
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.9)); // 1
// (1) Math.ceil()   天花板 向上取整 往最大取值
console.log(Math.ceil(1.1)); // 2
console.log(Math.ceil(1.9)); // 2
// (1) Math.round()  四舍五入 .5特殊往大去取
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.5)); // 2
console.log(Math.round(-1.5)); // -1

3.4.4 Math对象随机数方法 random() 返回一个随机的小数 [0,1) 范围左闭右开 这个方法里面不跟参数。

console.log(Math.random());

需求:需要得到俩个数之间的随机整数 并且 包含这2个整数

// Math.floor(Math.random() * (max - min + 1)) + min;
function getRandom(min,max){
    //向下取整,因为要包括最大数,所以要加1
    return Math.floor(Math.random() * (max - min + 1)) + min; 
}
console.log(getRandom(1,10)); //以1~10为例

班级随机点名 (人名随机)

function getRandom(min,max){
    //向下取整,因为要包括最大数,所以要加1
    return Math.floor(Math.random() * (max - min + 1)) + min; 
}
var arr = ['张小凡','张晓樊','张二凡','张三凡','张四凡'];
console.log(arr[getRandom(0,arr.length-1)]);

猜数字游戏

function getRandom(min,max){
    //向下取整,因为要包括最大数,所以要加1
    return Math.floor(Math.random() * (max - min + 1)) + min; 
}
var random = getRandom(1,100);
while(true){
    var num = prompt('1~100之间请输入您猜的数字:');
    if(num>random){
        alert('猜大了!');
    }else if(num<random){
        alert('猜小了!');
    }else{
        alert('恭喜您!猜对了');
        break;//退出死循环
    }
}

3.4.5 Date() 日期对象 是一个构造函数 必须使用 new 来调用创建我们的日期对象

// 1.使用Date 如果没有参数 返回当前系统的当前时间
var date = new Date();
console.log(date);
// 2.参数常用的写法 数字型 2022, 5, 19 或者是字符串型 '2022-5-19 9:9:9'
var date1 = new Date(2022, 5, 19);
console.log(date1); //返回的是4月不是5月 西方月份从零开始
var date2 = new Date('2022-5-19 9:9:9');
console.log(date2);

完了,暴露我写文章的时间了,寄~~~,熬夜对身体不好,亲身经历,谨记!!!,哈哈哈

格式化日期 年月日

var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1; //记得月份要加1
var dates = date.getDate();
var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day = date.getDay();
console.log('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);

格式化日期 时分秒

var date = new Date();
console.log(date.getHours()); // 时
console.log(date.getMinutes()); // 分
console.log(date.getSeconds()); // 秒

要求封装一个函数返回当前的时分秒

function getTime(){
    var time = new Date();
    var h = time.getHours();
    h = h < 10 ? '0' + h : h;
    var m = time.getMinutes();
    m = m < 10 ? '0' + m : m;
    var s = time.getSeconds();
    s = s < 10 ? '0' + s : s;
    return h + ':' + m + ':' + s;
}
console.log(getTime());

获得Date总的毫秒数(时间戳)

注意:不是当前的毫秒数 而是距离1970年1月1号过了多少毫秒

// 获得方法
// 1.通过 valueOf() getTime()
var date = new Date();
console.log(date.valueOf()); //就是现在距离1970.1.1 总的毫秒数
console.log(date.getTime());
// 2.简单的写法(最常用)
var date1 = +new Date(); // +new Date() 返回的就是总的毫秒数
console.log(date1);
// 3.H5 新增的 获得Date总的毫秒数
console.log(Date.now()); //要考虑浏览器版本的兼容性

倒时器

function countDown (time) {
    var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
    var inputTime = +new Date(time); // 返回的是用户输入时间的总的毫秒数
    var times = (inputTime - nowTime) / 1000; // time是剩余时间总的秒数
    var d = parseInt(times / 60 / 60 / 24); //天
    d = d < 10 ? '0' + d : d;
    var h = parseInt(times / 60 / 60 % 24); //计算小时
    h = h < 10 ? '0' + h : h;
    var m = parseInt(times / 60 % 60); //计算分数
    m = m < 10 ? '0' + m : m;
    var s = parseInt(times % 60); //计算当前秒数
    s = s < 10 ? '0' + s : s;
    return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2022-5-20 2:40:00'));
var date = new Date();
console.log(date);

到这,差不多已经介绍完了,进阶部分下期在补充~

最后祝大家 5.20快乐~~~,哈哈哈。

上一期:

https://blog.csdn.net/qq_53123067/article/details/124766654?spm=1001.2014.3001.5501

下一期:

未完待续.....

标签: 前端 javascript

本文转载自: https://blog.csdn.net/qq_53123067/article/details/124872791
版权归原作者 亦世凡华、 所有, 如有侵权,请联系我们删除。

“JavaScript入门到精通(四)连载”的评论:

还没有评论