什么是对象,其实就是一种类型,即引用类型。而对象的值就是引用类型的实例。在ECMAScript中引用类型是一种数据结构。用于将数据和功能组织在一起,它也常被称做类,但ECMAScript中却没有这种东西。虽然ECMAScript是一门面向对象的语言。却不具备传统面向对象语言所拥有的类和接口等基本结构。
万物皆对象,除了数字,字符,布尔这种绝对值以外的所有部分都是对象,对象是类的实例化体现,类是对象的抽象体现。
对象是一个个体,他具备自身类的所有属性和方法。
//对象中有属性和方法
//属性就是key对应的value是一个值
//方法就是key对应的value是一个函数
var obj ={
a : 3 ,
b: 2,
c : functionx(){
console.log("aaa");
};
//使用JSON无法选中dui
var str = JSON.stringify(obj);
console.log(str);
//将函数转为字符串重新赋值给c属性
obj.c = obj.c.toString();
//转为JSON字符
var str = JSON.stringify(obj);
//恢复为对象
var o = JSON.parse(str);
console.log(o);
obj.属性=属性值
obj.方法=方法函数
obj[属性]=属性值
obj[方法]=方法函数中括号中的属性和方法必须是字符串,
如果是变量,该内容必须是字符型变量。
var obj = {};
花括号在语言中是指代码块的意思,在obj也相当于一个代码块。
obj自身在使用中可以完成和丰富各种代码块。
var obj={
属性:属性值,
方法:方法函数
}
在函数中,有时候需要返回一个对象,这时候,我们通常使用花括号的形式来返回对象
function abc(){
return {
属性:属性值,
方法:方法函数
}
}
var obj= {};
obj.a = 1;//直接描述对象下有一个a的属性值,值是1
obj["a"]= 1;//对象[字符key]=value;
//key就是属性名称,必须是字符串(ES5)
var a = "a";
obj[a]= 1;// 中括号的方式是可以带入变量作为key的,点语法不能使用变量
var obj={a:1,b:2,c:3,d:{a:1,b:2}};
for(var prop in obj){
//prop就是obj下的所有属性名key
//每循环一次就将属性名给prop变量
console.log(prop ,obj[prop]
}
//浅复制
var obj1 ={};
for(var prop in obj1){
obj1[prop]=obj[prop];
}
//obj.a= 10;
//复制后切断引用关系,所以源对象属性值改变,新对象不变
obj.d.a=10;
console.log(obj1);
var obj = Object.create();
Object.create(proto, [ propertiesObject ])
proto对象原型
propertiesObject 一组属性和值,该参数对象不能是 undefined,
另外只有该对象中自身拥有的可枚举的属性才有效,
也就是说该对象的原型链上属性是无效的。
该方法可以针对已知对象创建新对象也可以创建一个空对象。
对象的属性和方法
delete
删除对象的属性
var obj={a:3,b:4}
delete obj.a;
也可以根据键值删除对象下的属性。
for in
var obj={a:1,b:3};
for(var str in obj){
console.log(obj[str]);
1. 函数基础
函数对任何语言来说都是一个核心的概念。函数,是一种封装(将一些语句,封装到函数里面)。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScript中的函数使用function关键字来声明,后跟一组参数以及函数体,也就是包裹在花括号中的代码块,前面使用了关键词 function:当调用该函数时,会执行函数内的代码。
function 函数名()
{
执行代码
}
函数声明
/*函数关键字 + 函数名 + (){
语句
函数体[]
}*/
//命名函数的创建
function fn(a,b){
console.log(a+b);
}
fn(3,4)
/*
注:1.函数命名跟变量一样,只能是字母、数字、下划线、美元符号,不能以数字开头。和变量名相同
2.后边()里放参数用的,参数就相当于变量,数量和名字可以自己定义
3.函数的后面{}里面是正式函数内的所有语句块,当执行函数时,就会执行{}中的内容
4.函数名:驼峰式命名法 ,首字母一般都是小写,如果该函数是构造函数,函数名首字母需要大写
5.在当前函数所在script标签创建时,优先将该函数存储在堆中,并且函数名存储在栈中
6.当前这个代码所在的script标签的上面的script的标签中任意函数和全局变量都是可调用的
*/
//匿名函数
fn();//执行会报错
var fn = function(){
}
//注意:代码运行到定义匿名函数后才可以调用该匿名函数
(function){
//自执行函数
}();
//构造函数定义函数
//可以动态构建函数
var fn = new;
Function ("a","b","console.log(a+b)");
fn(3,5);
函数调用
函数必须通过调用才可以使用。调用时通过其函数名调用,后面要加上一对圆括号
语法:
函数名字();
函数,是一种封装,就是将一些语句,封装到函数里面。通过调用的形式,执行这些语句
//练习:当点击按钮时执行fn()函数
<html>
<head>
<style>
*{
margin:0;
padding:0;
div{
width:200px;
height:200px;
margin:300px auto;
background:pink;
}
</style>
</head>
<body>
<div onclick="changeBgColor()">点击改变背景颜色</div>
<script>
var div = getElementByTagName("div");
function changeBgColor(){
div.style.backgroundColor = "purple";
}
</script>
<body>
<html>
函数的优点
函数的功能、好处:
1)将会被大量的语句写在函数里面,这样以后需要这些语句的时候,直接调用函数,不用重写那些语句
2)简化编程,让编程变得模块化
作用域
//函数外的变量 在函数中可以调用到
//函数内定义的变量不能备函数外调用
function fn(){
var a = 10;
//在函数内使用var定义的变量就是局部变量
//在函数外使用var定义的变量就是全局变量
//不使用var直接给一个变量赋值就是相当于给window增加一个属性,那么这个属性也就是全局变量
}
fn();
console.log(a);
//var是定义变量,如果在函数中没有用var定义变量,直接使用变量,该变量是全局变量
function fn(){
a = 10;
}
fn();
console.log(a);
//this === window
function fn(){
//window被省略了,如果没有使用var定义变量就意味着直接在window对象下增加这个属性
a = 10;
}
fn();
console.log(a);
var a = 10;
function fn(){
//在函数任意位置使用var定义的变量,在该函数任意位置都认为该变量是局部变量
console.log(a);//undefined
var a =5;
console.log(a);//5
//有局部变量时,先调用局部变量,没有局部变量才调用全局变量
}
fn();
console.log(a);//10
//全局变量+局部变量
var a = 10;
function fn(){
var a = 20;
console.log(a + window.a);//30
}
fn();
function fn(a){
console.log(a);//5
//参数就是局部变量
}
fn(5);
var a = 10;
function fn(a){
consoloe.log(a);//5
var a = 20;//这里相当于重新定义了一个局部变量a
}
fn(5);
a(a);
//a都是全局变量,下面a=10还没有运行,所以在这里全局变量就是函数a,我们把函数a当前参数填入
var a = 10;
//覆盖了函数a,函数a在这里也是全局变量
function a(a){
console.log(a);/* f a(a){
console.log(a);
var a = 10;
}*/
var a = 10;
}
//a(a); //报错
2. 参数
实参:真实的数值、字符串
形参:一个接受实参的变量
function fn(a,b){
//a,b是参数,参数可以是任意内容,如果没有对应的填入,该参数就是undefined
//执行函数时,填入的参数就相当于给参数赋值
//js是一个弱类型语言就,因此,参数不能强制约定类型
//ES5中不能设置参数的默认值
console.log(a+b);
}
fn(2,4);
//执行函数时填入值与函数参数顺序是一一对应关系
function fn(obj){
// 相当于给obj赋值一个o,obj和o的引用地址相同
// 当修改obj的属性时,全局的o属性也会被修改
obj.a=10;
}
var o={a:1};
fn(o);
function fn(obj){
// 重新设置了obj的新的引用地址
obj={
a:3
}
}
var o={a:1};
fn(o);
//如果参数的数量不确定,就不设置参数
//获取最大数
function getMaxValue(){
// console.log(arguments);//ES5以上版本时尽量少用,arguments参数集
if(arguments.length===0) return;
var max=arguments[0];
for(var i=1;i<arguments.length;i++){
max=max>arguments[i] ? max : arguments[i];
}
console.log(max);
}
getMaxValue(1,4,7,2,3,10);
//arguments.callee 该函数自己,用于匿名函数中调用自身函数
//argument.callee.caller 调用当前函数的环境函数
3. return
return break continue
return 只能使用在函数中,函数外不能使用,无视任何内容直接跳出函数
break 用于switch或者循环语句中,跳出当前循环或者锚点循环,或者switch语句,循环外的语句继续执行
continue 仅跳出当前次循环,继续下一次循环,只能用于循环语句中
补充扩展:
//在页面中生成一个div点击实现红蓝颜色切换(下面仅书写js部分)
//把id是div0的元素获取成为DOM变量
var div = document.getElementById("div0");
//设置行内样式
div.style.width = "100px";
div.style.height = "100px";
div.style.backgroundColor = "red";
var bool = false;
div.onclick = function () {
bool = !bool;
div.style.backgroundColor = bool ? "blue" : "red";
}
setInterval(function(){
// 间隔多长时间执行该函数,时间是毫秒数
console.log("aa");
},1000);
var time=0;
// setInterval(执行的函数,间隔的时间);返回一个数值,可以根据这个数值清楚执行函数
var ids=setInterval(animation,1000);
function animation(){
time++;
if(time>5) clearInterval(ids);//clearInterval(创建时间间隔id) 清楚时间间隔执行
console.log("aa");
}
// 多少时间后执行该函数
// setTimeout(执行的函数,间隔的时间);//多长时间后执行
var ids=setTimeout(function(){
console.log("aa");
clearTimeout(ids);//清除时间间隔,每次用完必须清除
},5000);
// setInterval和setTimeout第三个参数都是可以给执行函数传入参数的
var ids=setInterval(animation,1000,5);
function animation(n){
}
//通过点击实现div块的静止与移动
var disc=0,bool=false;
init();
function init() {
var div = document.getElementById("div0");
div.style.width = "50px";
div.style.height = "50px";
div.style.backgroundColor = "red";
div.style.position = "absolute";
div.style.left="0px";
div.onclick=function(){
bool=!bool;
}
setInterval(anmiation,16,div);
}
function anmiation(div){
if(!bool) return;
disc++;
div.style.left=disc+"px";
}
//如果在函数最后一句没有返回值的情况下,尽量不要写return
function fn(){
for(var i=0;i<10;i++){
if(i===5) return;
}
console.log("a");
}
fn();
//return有时候可以替代break
//return返回值
// 可以允许函数返回一个值,仅一个。。
function fn(){
return "a";
}
// 函数在执行时,将会返回一个结果,如果函数中没有return,就会返回undefined
var s=fn();
console.log(s);
function randomColor(alpha){
// 如果没有参数,随机
alpha=alpha==undefined ? Math.random().toFixed(2) : alpha;
// 传入的参数转换为数值
alpha=Number(alpha);
// 如果传入的参数是非数值,就让透明度为1
if(isNaN(alpha))alpha=1;
var color="rgba(";
for(var i=0;i<3;i++){
color+=parseInt(Math.random()*256)+",";
}
color+=alpha+")";
return color;
}
console.log(randomColor(true));
//return返回对象
//可以返回多个值
function fn(w,h){
// var perimeter=(w+h)*2;
// var area=w*h;
return {
perimeter:(w+h)*2,
area:w*h
}
}
console.log(fn(5,6));
//return返回函数
//返回函数执行的结果
function fn(){
return fn1();
}
function fn1(){
return 1;
}
console.log(fn());
// 返回函数体
// 闭包
function fn(n){
return function(m){
// console.log(n+m);
return n+m;
}
}
var f=fn();
f();
console.log(fn(3)(5));
4.回调函数
下面为几个示例
//1定义一个回调函数
function callBack(){
}
setInterval(callBack,1000);
//2
function fn1(f){
f();
}
function fn2(){
console.log("aaa");
}
fn1(fn2);
//3
var i=0;
function fn1(f){
console.log("a");
f(fn1);
console.log(i);
}
function fn2(f){
i++;
console.log("b");
if(i<6000) f(fn2);
}
fn1(fn2);
// 堆栈溢出 递归或者回调的次数过多,没有阻止递归或者回调的条件
//通过回调函数实现“红”“绿”“黄”在控制台的交替
function getLight(first,second,third){
first(second,third);
}
function getRedLight(fn,fn1){
var f=arguments.callee;
var ids=setTimeout(function(){
console.log("红灯");
clearTimeout(ids);
fn(fn1,f);
},1000);
}
function getYellowLight(fn,fn1){
var f=arguments.callee;
var ids=setTimeout(function(){
console.log("黄灯");
clearTimeout(ids);
fn(fn1,f);
},1000);
}
function getGreenLight(fn,fn1){
var f=arguments.callee;
var ids=setTimeout(function(){
console.log("绿灯");
clearTimeout(ids);
fn(fn1,f);
},1000);
}
getLight(getGreenLight,getYellowLight,getRedLight);