来来来,JavaScript核心基础语句送给你们 学JS你不会DOM算真的学会了吗? 对JavaScript中的 事件 进行疯狂 处理 用BOM来实现轮播图效果 我们来实现创建JavaScript中的自定义对象 JS中构造函数的原型prototype 还不明白JS中的内置对象吗? 快来这里! JavaScript中数据如何存储在客户端?带你看看Cookie和WebStorage
什么是对象:
万物皆对象,如手机、电脑、汽车、坐姿、学生、猫、狗等实现世界中充满了对象,符合人们的思维习惯对象具有特征和行为:
特征:对象具有的属性,如学生的姓名、年龄等行为:对象具有的能力,如学生可以学习、跑步、做自我介绍JavaScript是基于对象的语言
对象具有的特征,称为属性对象具有的行为,称为方法三种方式:
使用Object //1.创建对象 var 对象名 = new Object(); //2.为对象添加属性 对象名.属性名 = 属性值; //3.为对象添加方法 对象名.方法名 = function(){ 方法体 } //4.调用属性和方法 对象名.属性名; 或 对象名['属性名']; 对象名.方法名; 或 对象名['方法名'](); <script> //1.创建对象 var stu = new Oject(); //2.为对象添加属性(特征) stu.name = 'tom'; stu.age = 27; stu['exam-score'] = 99; //对于特殊的属性名,需要使用中括号[]方式来定义 stu[24] = '科比'; //3.为对象添加方法 stu.study() = function(){ console.log('学习'); } stu.run() = function(){ console.log('跑步'); } stu.show() = function(){ console.log('我叫'+stu.name+',年龄,'+this.age); } //4.调用对象的属性和方法 console.log(stu.name,stu['name']); console.log(stu.age,stu['age']); console.log(stu['exam-score']); console.log(stu[24]); stu.study(); stu.run(); stu.show(); </script>使用构造函数
用来创建对象的函数,称之为构造函数或构造器,相当于自定义了一个类型
function 构造函数名(形参1,形参2){ //为了区别与普通函数,构造函数名建议首字母大写 this.属性名 = 形参1; this.属性名 = 形参2; this.方法名 = function(){ 方法体 }; } var 对象名 = new 构造函数(实参1,实参2); //定义一个带参的构造函数 function Student(name,age){ this.name = name; //此处的this表示将来创建的对象 this.age = age; this.study = function(){ console.log('学习'); } this.run = function(){ console.log('跑步'); } this.show = function(){ console.log('我叫'+this.name+',年龄,'+this.age); } } var stu1 = new Student('tom',18); //通过new的方式来调用构造函数 console.log(stu1.name,stu1.age); stu1.show(); var stu2 = new Student('alice',27); console.log(stu2.name,stu2.age); stu2.show();使用对象字面量
多个属性之间以逗号隔开,属性名和属性值之间以冒号隔开
var 对象 = { 属性名:属性值, 属性名:属性值, 方法名 = function(){ 方法体 } }; var stu = { name:'Zack'; age:18; 'exam-score':100; //特殊名称必须用引号引起来 study:function(){ console.log('学习'); } show:function(){ console.log('我叫'+this.name+',年龄:'+this.age); } } console.log(stu.name,stu['name']); stu.study(); stu.show();this表示当前对象
函数中的this,表示调用函数的当前对象 <script> var a = 8; function f1(){ console.log(this); //此处的this表示window,因为是由window调用 //解决局部变量和全局标量同名的问题 console.log('局部变量:',a); console.log('全局变量:',window.a); console.log('全局变量:',this.a); } f1(); //shenglve了window,实际的函数调用者就是window对象 //window.f1(); </script> 事件绑定的匿名回调函数中的this,表示事件源 <script> //事件绑定的匿名回调函数中的this,表示事件源 window.onload = function(){ document.querySelector('#btn').onclick = function(){ console.log(this); //此处的this表示事件源,即触发事件的目标元素 } } </script> <body> <button id="btn">点我</btn> </body> 构造函数中的this,表示new出来的当前对象 <script> //构造函数中的this,表示将来new出来的对象 var name='科比'; function Student(name,age){ this.name = '汤姆'; //此处的this表示当前对象,即将来创建出的对象 this.age = age; console.log('局部变量(形参):',name); //tom console.log('对象的属性',this.name); //汤姆 console.log('全局变量:',window.name); } var stu = new Student('tom',11); console.log(stu); </script>通过这两个例子我们就可以看出,基本数据类型和引用数据类型变量之间赋值的情况是不一样的,这就是因为它们的存储方式不同。
栈内存
基本数据类型的变量和引用数据类型的变量的引用会存储再栈内存中,存取速度比较快
堆内存
引用数据类型的数据会存储再堆内存中,存取速度较慢。
基本类型作为方法的参数
传递的是参数的值
引用类型作为方法的参数
传递的是参数的引用
//将基本数据类型作为参数,传递的是值 function f1(args){ args = 8; //再函数内部修改参数的值,不会影响外部变量 } var a = 5; f1(a); //按值传递 console.log(a); //将引用数据类型作为参数,传递的是地址 function f2(agrs){ agrs.name='Alice'; //在函数内部修改参数的值,会映像外部变量 } var stu1 = { name:'Tom', age:18, gender:'male' } f2(stu1); //按引用传递 console.log(stu1);闭包是JS中特有的现象,如何理解闭包?
在一个函数内部又定义了一个函数,这个定义在内部的函数,就是闭包。闭包就是能够读取其他函数内部变量的函数。闭包是在某个作用域内定义的函数,该函数可以访问这个作用域内的所有变量。从作用上来说,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包的用途:
在函数的外部,可以读取到函数内部的变量让变量的值始终保存在内存中(不会被垃圾回收器回收) <script> //作用1:再函数的外部,可以读取到函数内部的变量 function f1(){ var n = 13; //局部变量 function f2(){ //这里的f2就是闭包 return n; //再内部函数f2中可以访问到外部函数f1中的局部变量 } return f2; } var fn = f1(); var n = fn(); //此时可以读取到函数f1内部的变量 console.log(n); //作用2:让变量的值始终保存在内存中(不会被垃圾回收期回收) function f1(){ va n = 99; function f2(){ console.log(n++); } return f2; } var fn = f1(); fn(); fn(); //函数执行多次都输出了连续的结果,说明f1函数中的局部变量n一直保存在内存中 </script>由于闭包会使函数中的变量都被保存再内存中,内存消耗会比较大。
如果内部函数使用外部函数的变量,在外部函数执行完之前变量会有改变时,内部只能获取最后改变的值,无法获取定义时的值,就会产生闭包。
解决方式:
不在函数内部定义函数,将函数定义在外部,在函数内部调用为元素附加属性,用来存储变量使用let来定义变量 //我们希望点击每一个li时打印‘点击了第i个li的字段’,但是我们使用闭包时输出的都是‘点击了第6个li’,这就是使用闭包出现了问题。 <script> //出现问题 function add(){ for(var i=1;i<=5;i++){ var li = document.createElement('li'); li.innerText = 'li'+i; li.onclick = function(){ //当点击li时在执行该回调函数中的代码,此时训话已经执行完 console.log('点击了第'+i+'个li'); //输出“第6个” } document.getElementById('myul').appendChild(li); } } //解决方法一:不在函数内部定义函数,将函数定义在外部,在函数内调用 function add(){ for(var i=1;i<=5;i++){ var li = createLi(i); document.getElementById('myul').appendChild(li); } } function createLi(num){ var li = document.getElement('li'); li.innerText = 'li'+num; li.onclick = function(){ console.log('点击了第'+num+'个li'); } return li; } //解决方法二:为元素附加属性,用来存储变量 function add(){ for(var i=1;i<=5;i++){ var li = document.getElementById('li'); li.innerText = 'li'+i; li.num = i; //设置属性 li.onclick = function(){ console.log('点击了第'+this.num+'个li'); } document.getElementById('myul').appendChild(li); } } //解决方法三:使用let来定义变量 function add(){ //使用let声明变量,支持块级作用域,它所声明的变量所在的区域不会受外部影响,称为暂时性死亡 for(let i=1;i<=5;i++){ var li = document.createElement('li'); li.innerText = 'li'+i; li.onclick = function(){ console.log('点击了第'+i+'个li'); } document.getElementById('myul').appendChild(li); } } </script> <body> <button onclick="add()">添加</button> </body>JavaScript Object Notation 是一种轻量级的数据交换格式,用于表示JavaScript对象的一种方式。
采用与编程语言无关的文本格式,易于阅读和编写,同时也易于解析和生成。
语法:{"属性名":属性值,"属性名":属性值......}
注意:
JSON结构是由一系列的键值对所组成的,称为JSON对象属性名使用双引号引起来JSON和对象字面量的区别:JSON的属性名必须加双引号,而对象字面量不用