JavaScript基础(3)

JavaScript基础(3)

作用域

作用域:变量可以起作用的范围。

全局变量和局部变量

  • 全局变量
    在任何地方都可以访问到的变量就是全局变量,对应全局作用域
  • 局部变量
    只在固定的代码片段内可以访问到的变量,最常见的例如函数的内部。对应局部作用域(函数作用域)
    不使用var声明的变量是全局变量,不推荐使用
    变量退出作用域之后会销毁,全局变量关闭网页或浏览器才会销毁
块级作用域

任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域
将这样的所有作用域列出来,可以有一个结构:函数内指向函数外的链式结构,就称作作用域

// 案例1:
function f1() {
    function f2() {
    }
}

var num = 456;
function f3() {
    function f4() {    
    }
}
在这里插入图片描述
// 案例2
function f1() {
    var num = 123;
    function f2() {
        console.log(num); 
    }
    f2();
}
var num = 456;
f1();
在这里插入图片描述

预解析

JavaScript代码的执行是由浏览器中的JavaScript解析器来执行。JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程
预解析过程:

  1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
  2. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会调用
  3. 先提升var,再提升function
    JavaScript的执行过程
// 案例1
var a = 25;
function abc() {
  alert(a); 
  var a = 10;
}
abc();


// 案例2
console.log(a);
function a() {
  console.log('aaaaa');
}
var a = 1;
console.log(a);

变量提升

  • 变量提升
    定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升
  • 函数提升
    JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面
// 1、-----------------------------------
var num = 10;
fun();
function fun() {
  console.log(num);
  var num = 20;
}
//2、-----------------------------------
var a = 18;
f1();
function f1() {
  var b = 9;
  console.log(a);
  console.log(b);
  var a = '123';
}
// 3、-----------------------------------
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);
}
 <script>
        var num = 12;  //全局作用域 0级作用域链
        function f1() {
            num = 15;    // 局部作用域 1级作用链
            function f2() {
                console.log(num);// 局部作用域 1级作用链
            }
            f2();
        }
        f1();
        console.log(num);
    </script>

对象

JavaScript中的对象其实就是生活中对象的一个抽象
JavaScript的对象是无序属性的集合,其属性可以包含基本值、对象或函数。对象就是一组没有顺序的值。我们可以把JavaScript中的对象想象成键值对,其中值可以是数据和函数。
对象行为和特征
特征***属性 行为—–方法

  • 对事物的特征在对象中用属性来表示。
  • 事物的行为在对象中用方法来表示。
对象创建方式

字面量:11 ‘abc’ true [] {} 等

var o = {
  name: 'zs,
  age: 18,
  sex: true,
  sayHi: function () {
    console.log(this.name);
  }
};

newObject()创建对象

var person = new Object();
person.name = 'zs';
person.age = 18;
person.sayHi: function () {
    console.log(this.name);
  }

工厂函数创建对象

function createPerson(name, age, job) {
  var person = new Object();
  person.name = name;
  person.age = age;
  person.job = job;
  person.sayHi = function(){
    console.log('Hello,everyBody');
  }
  return person;
}
var p1 = createPerson('张三', 22, 'actor');
  • 自定义构造函数
function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayHi = function(){
  	console.log('Hello,everyBody');
  }
}
var p1 = new Person('张三', 22, 'actor');

属性和方法

如果一个变量属于一个对象所有,那么该变量就可以称之为该对象的一个属性,属性一般是名词,用来描述事物的特征
如果一个函数属于一个对象所有,那么该函数就可以称之为该对象的一个方法,方法是动词,描述事物的行为和功能

new关键字

构造函数,是一种特殊的函数。主要用来字创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。

  • 构造函数用于创建一类对象,首字母要大写。
  • 构造函数要和new一起使用才有意义。
    new在执行时会做四件事
  • new会让内存中创建一个空对象
  • new会让this指向这个新对象
  • 执行构造函数 目的:给这个新对象加属性和方法
  • new会返回这个新对象

this详解

JavaScript中的this指向:

  1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定
  2. 一般函数直接执行,内部this指向全局window
  3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象
  4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到这个隐式对象身上,后通过new关键字来调用,从而实现实例化

对象的使用

遍历对象的属性

通过for…in 语法可以遍历一个对象

var obj = {};
for (var i = 0; i < 10; i++) {
  obj[i] = i * 2;
}
for(var key in obj) {
  console.log(key + "==" + obj[key]);
}
删除对象的属性
function fun() { 
  this.name = 'mm';
}
var obj = new fun(); 
console.log(obj.name); // mm 
delete obj.name;
console.log(obj.name); // undefined
简单类型和复杂类型的区别

基本类型又叫做值类型,复杂类型又叫做引用类型
值类型:简单数据类型,基本数据类型,在存储时,变量中存储的是值本身,因此叫做值类型。
引用类型:复杂数据类型,在存储是,变量中存储的仅仅是地址(引用),因此叫做引用数据类型。

  • 堆和栈
    堆栈空间分配区别:
  1. 栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
  2. 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收,分配方式到是类似于链表。
    注意:JavaScript中没有堆和栈的概念,此处我们用堆和栈

基本类型在内存中的存储

在这里插入图片描述

复杂类型在内存中的存储

在这里插入图片描述

基本类型作为函数的参数

在这里插入图片描述

复杂类型作为函数的参数

在这里插入图片描述

内置对象

JavaScript中的对象分为3种:内置对象、浏览器对象、自定义对象
JavaScript提供多个内置对象:Math/Array/Number/String/Boolean
对象只有带有属性和方法的特殊数据类型

Math对象

Math不是构造函数,它具有数学常数和函数的属性和方法,都是以静态成员的方式提供
跟数学相关的运算来找Math中的成员(求绝对值、取整)
演示:Math.PI、Math.random()、Math.floor()/Math.ceil()、Math.round()、Math.abs() 、Math.max()

Math.PI						// 圆周率
Math.random()				// 生成随机数
Math.floor()/Math.ceil()	 // 向下取整/向上取整
Math.round()				// 取整,四舍五入
Math.abs()					// 绝对值
Math.max()/Math.min()		 // 求最大和最小值

Math.sin()/Math.cos()		 // 正弦/余弦
Math.power()/Math.sqrt()	 // 求指数次幂/求平方根

案例:

    <script>
        // - 求10-20之间的随机数  [10, 20]   整数
        // Math.random()  ->  [0, 1)  小数
        // Math.random() * 20   ->   [0, 20)  包含小数部分
        // Math.random() * (20 - 10)  -> [0, 10)  包含小数部分
        // Math.random() * (20 - 10) +  10 -> [10, 20)  包含小数部分
        // 求10-20之间的随机数
        var a = 10;
        var b = 20;
        // math.random() 范围在[0,1)
        console.log(parseInt(Math.random() * (b - a) + a));
        // 随机生成颜色RGB  [0,255]
        function randomRgb(min, max) {
            var color1 = Math.floor(Math.random() * (max - min + 1) + min);
            var color2 = Math.floor(Math.random() * (max - min + 1) + min);
            var color3 = Math.floor(Math.random() * (max - min + 1) + min);
            return 'rgb(' + color1 + ',' + color2 + ',' + color3 + ')';
        }
        // 点击按钮调用随机生成颜色方法
        function fn() {
            var a = randomRgb(0, 255);
            // 改变body的背景
            document.body.style.backgroundColor = a;
        }

        console.log(a);
        // 模拟min()和max()
        var MyMath = {
            max: function () {
                var max = arguments[0];
                for (let i = 1; i < arguments.length; i++) {
                    if (max < arguments[0]) {
                        max = arguments[i];
                    }

                }
                return max;
            }
        }
        console.log(MyMath.max(20, 20, 30, 40))
    </script>

math不是构造函数,静态成员直接math.random() date是构造函数需要new date()

Date对象

创建Date实例用来处理日期和时间。Date对象基于1970年1月1日。

// 获取当前时间,UTC世界时间,距1970年1月1日(世界标准时间)起的毫秒数
var now = new Date();
console.log(now.valueOf());	// 获取距1970年1月1日(世界标准时间)起的毫秒数

Date构造函数的参数
1. 毫秒数 1498099000356		new Date(1498099000356)
2. 日期格式字符串  '2015-5-1'	 new Date('2015-5-1')
3. 年、月、日……				  new Date(2015, 4, 1)   // 月份从0开始

//获取日期的毫秒形式
var now = new Date();
// valueOf用于获取对象的原始值
console.log(date.valueOf())	

// HTML5中提供的方法,有兼容性问题
var now = Date.now();	

// 不支持HTML5的浏览器,可以用下面这种方式
var now = + new Date();			// 调用 Date对象的valueOf() 

//日期格式化方式
toString()		// 转换成字符串
valueOf()		// 获取毫秒值
// 下面格式化日期的方法,在不同浏览器可能表现不一致,一般不用
toDateString()
toTimeString()
toLocaleDateString()
toLocaleTimeString()

//获取日期指定部分
getTime()  	  // 返回毫秒数和valueOf()结果一样,valueOf()内部调用的getTime()
getMilliseconds() 
getSeconds()  // 返回0-59
getMinutes()  // 返回0-59
getHours()    // 返回0-23
getDay()      // 返回星期几 0周日   6周6
getDate()     // 返回当前月的第几天
getMonth()    // 返回月份,***从0开始***
getFullYear() //返回4位的年份  如 2016

案例:

   <script>
        // 写一个函数,格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
        function formatDate(data) {
            // 先判断是不是date格式
            if (!(data instanceof Date)) {
                console.error('格式不正确!')
                return;
            }
            // 获取时间日期
            var year = data.getFullYear(),
                month = data.getMonth() + 1,
                day = data.getDate(),
                hour = data.getHours(),
                minute = data.getMinutes(),
                second = data.getSeconds();
            // 判断是否大于10
            month = month < 10 ? '0' + month : month;
            day = day < 10 ? '0' + day : day;
            hour = hour < 10 ? '0' + hour : hour;
            minute = minute < 10 ? '0' + minute : minute;
            second = second < 10 ? '0' + second : second;
            return year + '-' + month + '-' + day + '-' + '' + hour + ':' + minute + ':' + second;
        }
        var test = new Date();
        var data = formatDate(test);
        console.log(data);
        // var test = new Date(2000, 3);
        // var data = formatDate(test);
        // console.log(data);


        // 计算两个时间段的差
        var d1 = new Date();
        var d2 = new Date(1945 - 4 - 5);
        console.log(d1 - d2);
    </script>

Array对象

创建数组对象的两种方式

  • 字面量方式
  • new Array()
// 1. 使用构造函数创建数组对象
// 创建了一个空数组
var arr = new Array();
// 创建了一个数组,里面存放了3个字符串
var arr = new Array('zs', 'ls', 'ww');
// 创建了一个数组,里面存放了4个数字
var arr = new Array(1, 2, 3, 4);


// 2. 使用字面量创建数组对象
var arr = [1, 2, 3];

// 获取数组中元素的个数
console.log(arr.length);
  • 检测一个对象是否是数组
    instanceof
    Array.isArray()
    函数的参数,如果要求是一个数组的话,可以用这种方式来进行判断
  • toString()/valueOf()
    toString() 把数组转换成字符串,逗号分隔每一项
    valueOf() 返回数组对象本身
    数组常用方法:push()、shift()、unshift()、reverse()、sort()、splice()、indexOf()
// 1 栈操作(先进后出)
push()
pop() 		//取出数组中的最后一项,修改length属性
// 2 队列操作(先进先出)
push()
shift()		//取出数组中的第一个元素,修改length属性
unshift() 	//在数组最前面插入项,返回数组的长度
// 3 排序方法
reverse()	//翻转数组
sort(); 	//即使是数组sort也是根据字符,从小到大排序
// 带参数的sort是如何实现的?
// 4 操作方法
concat()  	//把参数拼接到当前数组
slice() 	//从当前数组中截取一个新的数组,不影响原来的数组,参数start从0开始,end从1开始
splice()	//删除或替换当前数组的某些项目,参数start, deleteCount, options(要替换的项目)
// 5 位置方法
indexOf()、lastIndexOf()   //如果没找到返回-1
// 6 迭代方法 不会修改原数组(可选)
every()、filter()、forEach()、map()、some()
// 7 方法将数组的所有元素连接到一个字符串中。
join()
  • 清空数组
    // 方式1 推荐
    arr = [];
    // 方式2
    arr.length = 0;
    // 方式3
    arr.splice(0, arr.length);
    案例:
 <script>
        var a = [1, 3, 7, 5];
        // 栈操作(先进后出)
        // push 参数会有多个,将来都会添加都数组最后
        a.push(4, 5);
        console.log(a);
        // pop返回数组的最后一个元素,并且会修改数组的长度就像截取字符串
        var last = a.pop();
        console.log(last);
        console.log(a.length);
        console.log(a);

        // 队列操作(先进先出)
        var array = [1, 2, 3];
        array.push(4);
        // 返回数组第一个元素
        var first = array.shift();
        console.log(first);
        console.log(array);
        // 在前面添加一个元素
        var first2 = array.unshift(0);
        console.log(array);
        // 3.排序方法
        //   reverse()  翻转数组
        var a1 = [1, 2, 3, 4, 5, 6];
        console.log(a1);
        var a2 = a1.reverse();
        console.log(a2);
        //sort 排序
        var a3 = [1, 8, 5, 0, 3];
        console.log(a3);
        var a4 = a3.sort();
        console.log(a4);
    </script>

基本包装类型

// 下面代码的问题?
// s1是基本类型,基本类型是没有方法的
var s1 = 'zhangsan';
var s2 = s1.substring(5);

// 当调用s1.substring(5)的时候,先把s1包装成String类型的临时对象,再调用substring方法,最后销毁临时对象, 相当于:
var s1 = new String('zhangsan');
var s2 = s1.substring(5);
s1 = null;
// 创建基本包装类型的对象
var num = 18;  				//数值,基本类型
var num = Number('18'); 	//类型转换
var num = new Number(18); 	//基本包装类型,对象
// Number和Boolean基本包装类型基本不用,使用的话可能会引起歧义。例如:
var b1 = new Boolean(false);
var b2 = b1 && true;		// 结果是什么

String对象

  • 字符串的不可变
    var str = ‘abc’;
    str = ‘hello’;
    // 当重新给str赋值的时候,常量’abc’不会被修改,依然在内存中
    // 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
    // 由于字符串的不可变,在大量拼接字符串的时候会有效率问题
  • 创建字符串对象
    var str = new String(‘Hello World’);
    // 获取字符串中字符的个数
    console.log(str.length);
  • 字符串对象的常用方法
// 1 字符方法
charAt()    	//获取指定位置处字符
charCodeAt()  	//获取指定位置处字符的ASCII码
str[0]   		//HTML5,IE8+支持 和charAt()等效
// 2 字符串操作方法
concat()   		//拼接字符串,等效于+,+更常用
slice()    		//从start位置开始,截取到end位置,end取不到
substring() 	//从start位置开始,截取到end位置,end取不到
substr()   		//从start位置开始,截取length个字符
// 3 位置方法
indexOf()   	//返回指定内容在元字符串中的位置
lastIndexOf() 	//从后往前找,只找第一个匹配的
// 4 去除空白   
trim()  		//只能去除字符串前后的空白
// 5 大小写转换方法
to(Locale)UpperCase() 	//转换大写
to(Locale)LowerCase() 	//转换小写
// 6 其它
search()
replace()
split()
fromCharCode()
// String.fromCharCode(101, 102, 103);	 //把ASCII码转换成字符串

// JavaScript 组成: ECMAScript BOM DOM
// ECMAScript:变量 注释 数据类型 类型转换 操作符 流程控制语句(判断和循环) 数组 对象 构造函数 内置对象
// JavaScript中的对象有三种:自定义对象、内置对象、浏览器对象
// ECMAScript中的对象: 自定义对象、内置对象
//
// 内置对象:Math/Array/Date…
//
// 最常用的属性和方法
//
// 查文档:MDN
案例:

  <script>
        // 1.charAt()   获取指定位置处字符
        // 2.charCodeAt()  获取指定位置处字符的ASCII码
        // 3.str[0]    HTML5,IE8+支持和charAt()等效
        var s = 'abcdef';
        console.log(s.charAt(0));
        for (let i = 0; i < s.length; i++) {
            console.log(s.charAt(i));
        }
        console.log(s.charCodeAt(0));
        // 字符串操作方法
        // concat()     拼接字符串,等效于+,+更常用
        // slice()      从start位置开始,截取到end位置,end取不到
        // substring()    从start位置开始,截取到end位置,end取不到
        // substr()  从start位置开始,截取length个字符

        // 位置方法
        // indexOf()       返回指定内容在元字符串中的位置
        // lastindexOf()    从后往前找,只找一个匹配的
        var s = '我是程序猿一只';
        // 第一个参数,截取的开始位置 0 1 2
        // 第二个参数,截取的长度
        // var newStr = s.substr(2, 2);
        // console.log(newStr);

        // // 'jdafjfsdfhfhs'  查找字符串中所有j出现的位置
        // var a = 'jdafjfsdfhfhs';
        // // 当查找不到的时候返回的是-1
        // console.log(a.indexOf('j', 0));
        // var index = -1;
        // do {
        //     index = a.indexOf('j', index + 1);
        //     if (index !== -1) {
        //         console.log(index);
        //     }
        // } while (index !== -1);

        var s = 'abcoefoxyozzopp';

        //  abc!efoxyozzopp
        //  只会替换第一个找到的字符串
        // s = s.replace('o', '!');
        // console.log(s);
        // 
        var index = -1;
        do {
            index = s.indexOf('o', index + 1);

            if (index !== -1) {
                // 替换
                s = s.replace('o', '!');
            }
        } while (index !== -1);
        console.log(s);

        // 去除空白
        // trim()   只能去除字符串中的位置

        //trim() 只可以去除字符串前后的空格
        var s2 = '   abc    vyx   xyx   ';
        console.log(s2.trim());
        //  思路1 可以把字符串中的所有 空格 字符串 用replace替换成 '' 空字符串
        // 思路2 使用split简化
        var str = 'a,b,c,d';
        var arr = str.split(',');
        console.log(arr.join('!'));
        var arr1 = s2.split(' ');
        console.log(arr1.join(''));

        // 大小写转换方法
        // to(local) UpperCase()   转换大写
        // to(local)LowerCase()    转换小写
        // 其他
        // search()  寻找         replace()    替换             split() 全部替换   要join() 方法
        // 获取url中?后面的内容
        // 例如:http://www.itheima.com/login?name=zs&age=18&a=1&b=2

        var url = 'http://www.itheima.com/login?name=zs&age=18&a=1&b=2';

        // console.log(url.substr(2));
        // var index = url.indexOf('?') + 1;
        // console.log(url.substr(index));


        // {
        //   name: 'zs',
        //   age: 18
        // }

        // 获取url后面的参数
        function getParams(url) {
            // 获取? 后面第一个字符的索引
            var index = url.indexOf('?') + 1;
            // url中?后面的字符串 name=zs&age=18&a=1&b=2
            var params = url.substr(index);
            // 使用& 切割字符串 ,返回一个数组
            var arr = params.split('&');
            var o = {};
            // 数组中每一项的样子 key = value
            for (var i = 0; i < arr.length; i++) {
                var tmpArr = arr[i].split('=');
                var key = tmpArr[0];
                var value = tmpArr[1];

                o[key] = value;
            }
            return o;
        }

        var obj = getParams(url);
        console.log(obj);

        console.log(obj.name);
        console.log(obj.age);


    </script>

这篇文章有 68 个评论

  1. İnstagram türk takipçi satın almak ve hesabını popülerliğe ulaştırmak için, ucuz takipçi sitemizden güvenilir takipçi satın al.

  2. Takipçi satın al

    İnstagram hesabına takipçi satın almak için, ucuz ve güvenilir takipçi sitemizi incele.

  3. takipçi satın al

    İnstagram hesabına takipçi satın al, instagram güvenilir takipçi sitesi ile yükselişe geç.

  4. Takipçi satın al

    Hadi sende takipcisepette ile güvenilir instagram takipçi satın alarak, takipçini arttır.

  5. Takipçi Satın Al

    İnstagram hesabına takipci satın almak için takipcisepette’yi incele.

  6. Ucuz Takipçi Satın Al

    İnstagram takipçi satın al son zamanlarda binlerce kişi tarafından araştırılmaktadır. İnstagram takipçi satın al hizmetinden faydalanmak için alacağınız sitenin güvenilir olması gerekmektedir. Güvenilir instagram takipçi satın almak için bizi tercih etmenizde fayda vardır. İnstagram takipçi satın al hizmeti için en güvenilir site ile karşınızdayız!

  7. Takipçi satın al

    İnstagram hesabınızı daha fazla kitleye ulaştırmak için sizde instagram takipçi satın alabilirsiniz. Türk ve gerçek aktif takipçileri profilinize hızla gönderin. Faturalı ve kurumsal alışveriş ile güvenilir takipçi satın alın. Hadi sende durma ve instagram takipçi satın almak için takipçi paketlerimizi incele.

  8. İnstagram takipçi satın almak için uygun zamanı bekleme. Hemen instagram takipçi satın alma sitemize gel ve instagram takipçi sayını arttır. İnstagram takipçi sayını yükseltmek için ucuz instagram takipçi satın al ve hesabını fenomen hale getir. İnstagram’da rakiplerini takipçi sayını arttırarak geç. İnstagram takipçi yükseltmek için hemen instagram takipçi satın al.

  9. takipçi satın al

    Güvenilir ve hızlı bir şekilde instagram takipçi satın al ve güvenilir takipçi satın al.

  10. Takipçi Satın Al

    İnstagram hesabına takipçi satın al, instagram güvenilir takipçi sitesi ile yükselişe geç.

  11. pornhub

    Wonderful article! That is the kind of information that should be shared
    across the net. Disgrace on Google for not positioning
    this put up upper! Come on over and discuss with my web site .

    Thank you =)

  12. ucuz takipçi satın al

    Spot on with this write-up, I absolutely feel this amazing site needs a
    great deal more attention. I’ll probably be returning to see more,
    thanks for the info!

发表评论