前端学习——JavaScript对象与函数

1.Object对象

1.为什么要使用对象

例如:

//用基础变量来表示一个人的基本信息(name gender age)
var name="张三";
var gender="男";
var age=36;

上面的特点就是,各个变量之间没有任何联系,都是相互独立的 。不能成为一个整体。
而对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。就像一个购物车,将零散的商品集中在一起,此时这些商品就都属于一个客人,即一个对象。

对象的分类:
1.内建对象:

  • 在ES标准中定义的对象,在任何的ES的实现中都可以使用
  • 例如:math ,string ,Boolean ,number ,function ,object等等;

2.宿主对象:

  • 由js的运行环境提供的对象,目前主要是指浏览器提供的对象;
  • 例如:BOM , DOM

3.自定义对象

  • 由开发人员自己定义的对象。

2.如何使用对象

  • 创建对象:var obj=new object();
    使用new关键字调用的函数object()是构造函数(constructor),构造函数是专门用来创建对象的函数。
  • 在对象中添加属性(在对象中添加的值成为属性)
    语法:对象.属性名=属性值
var obj=new object();
obj.name="张三";
obj.gender="男";
obj.age="18";
console.log(obj);

在这里插入图片描述

  • 读取对象中的属性
    语法:对象名.属性名; 例如:console.log(obj.name);//输出name的值
    注意:读取一个属性时没有指定对象会报错,但时指定了对象,后接一个不存在的属性 不会报错,而会返回undefined;

  • 修改对象属性值
    语法:对象名.属性名=新值; 例如:obj.age=20;

  • 删除对象属性值
    语法:delete 对象名.属性名;

3.属性名和属性值

属性名:

  • 对象的属性名不强制要求遵循标识符的规范;什么名字都可以使用(var int 等等)
  • 最好按照标识符的规范去命名。
  • 使用特殊属性名:
    当写obj.123=456;时会报错。123是数值不是字符串。
    这个时候就要使用 [] 而不是 .了;[]用于特殊的属性名;
    语法:obj["属性名"]=属性值; 例如:obj["123"]=456;
    读取时也要使用该方式console.log(obj["123"]);

使用[]去操作属性可以更加灵活。[]中可以直接传递一个变量,变量为多少就读取什么属性;
例如:

obj["123"]=456;
var n="123";
console.log(obj[n]);//返回456
//这样操作。以后只需要改 n 的值就能访问别的属性,不会写死。

属性值:
JS对象的属性值可以是任意的数据类型;obj.test= true ;
还可以是一个对象,就像一个二维数组一样,对象属性值又是一个对象

var obj=new object();
var obj2=new object();
obj.test=obj2;

in运算符
使用in运算符检查一个对象中是否含有某个属性,在看别人代码时可以使用in来看是否使用了某属性。
如果有返回true,没有返回false。

语法:"属性名" in 对象;例如:console.log("name" in obj);
属性可以是函数,写在对象里的函数称为方法,调用对象里的函数叫做调用某对象的方法。

4.引用数据类型的特别之处

JS的变量都是保存在栈内存中的。

基本数据类型的值都是直接存储在栈内存中,值与值之间相互独立存在,一个变量改变不会影响其他变量。例如:

var a=123;
var b=a;
a++;
console.log(a);//124
console.log(b);//123  a的值改变没对 b产生影响;

对象是保存在堆内存中的,每创建一个对象就会在堆内存中开辟一个新的空间,而对象名作为变量保存在栈中,其对应的对象值为堆内存的一个内存地址(对象的引用),如果两个对象保存的是同一个内存地址,那么他们其中一个做出改动就会影响到另一个对象。例如:

var obj=new object();
obj.name="123";
var obj2=obj;
obj.name="124";
console.log(obj.name);//输出124
console.log(obj2.name);//输出124,而不是123.因为他们对应的都是同一个存储空间。

obj2=NULL:obj2的值(内存地址变为NULL)obj2和obj的联系断开。

另外:两个基本数据类型比较,值一样,就相等。但两个对象的属性都一样,该两个对象不相等,因为比较时不会看属性,而是直接看栈内存中的内存地址值,该值不会一样,所以两个对象不会相等;

var obj=new object();
obj.name="xxx";
var obj2=new object();
obj2.name="xxx";
console.log(obj==obj2);//输出false,不相等。

5.对象字面量

使用字面量来创建对象
var obj={}{}就是字面量;是new object()的一种简单方式;
使用对象字面量,可以在创建对象时直接添加对象的属性;

语法:var 对象={属性名:"属性值",属性名:"属性值"........}

对象字面量中的属性名可以加双引号,建议不加,本来就是字符串,但如果使用特殊字符时一定要加双引号"$%#@12".

属性名和属性值是一组一组的名值对结构,该结构中名和值之间使用连接,多个名值之间使用,隔开。最后一个后面不要跟,,会有错。

var obj={
name:"张三",
age:18,
gender:"男",
text:{sno:1234}//名为text的对象
}

6.枚举

为了知道对象里都有什么属性,就需要枚举对象中的属性。
使用 for.....in语句
语法:for(var 变量 in 对象){}
例子:

var obj=new Object();
     obj.name="张三";
     obj.gender="男";
    obj.age="18";
     for(var n in obj){
          console.log(n);
     }

在这里插入图片描述
for—in语句有几个属性就会执行几次,每一次都会把一个属性名赋值给前面定义的变量,直到所有属性都被检索。
使用该方法同样能输出所有属性值:console.log("属性值:"+n+":"+obj[n]);//输出属性值,不能使用obj.n,这个是值名为n的属性,而不是n变量。

2.函数

函数也是一个对象(对象能做的,函数都能做),除了那五种基本类型外其他都是对象object。document,console等等都是对象。
函数中可以封装一些功能(代码),在需要时可以通过函数来调用这些功能(代码)。
调用语法:函数对象();调用后函数里的代码将会按顺序执行。例子:fun():调用函数,fun:函数对象

1.创建一个函数对象

方法一:(不使用)
将封装的代码以字符串的形式传递给构造函数,因为函数本质也是对象,拥有对象的一切性质包括设立属性值obj.name=“张三”;
例子:

var fun=new function("console.log('第一个函数')");
//fun:函数名;
//function:构造函数

方法二:(推荐使用)
使用函数声明来创建一个函数。使用typeof 来检查函数的属性,返回的是function。直接console.log(函数名不带调用的括号),输出的是其的代码。
语法:function 函数名([形参1,形参2,形参3,形参N....])//[]内表示可以可没有
          {语句代码};
例子:

function fun2(){
console.log("这是第二个函数");
};

方法三:
使用函数表达式来创建一个函数(匿名函数,需要为其赋个值才能调用)
语法:var 函数名=function([形参]){语句}
例子:

var fun3=function(){
console.log("这是第三个函数");
};

2.函数的参数

例子:

function sun(a,b){
console.log(a+b);
}
sum(1,2)

上面的a和b表示的是形参,sum(1,2)里的是实参,实参传递给形参,函数再利用形参进行运算。
注意:

  • 调用函数时,解析器不会检查实参的类型,所以要注意是否会接收到非法的参数,如果会的话,就要对参数进行类型检查。(实参可以是任意的数据类型)
  • 调用函数时解析器也不会检查实参得数量,多余实参不会被赋值,如果实参得数量少于形参,那么多出来得形参为undefined。
  • 在参数较多的时候(要简便),可以将参数封装到对象中,然后通过对象进行传递。
  • 函数也可以作为参数传递(常用),记住函数名加括号是调用,用的是函数返回值,不加括号,用的是函数本身。

3.返回值

和c语言一样使用return来返回值。
例子:

function sum(a,b,c){
var d=a+b+c;
return d;
};
var result=sum(1,2,3);//result=6

在函数中return后得所有语句都不会再被执行了,可以使用return来结束整个函数。
如果光写一个return后不带任何值,那么返回得会是undefined,不写return也是也是返回undefined。而且return后可以跟任意类型的值(也可以是对象,函数)。

4.立即执行函数

函数定义完,立即被调用执行,只会执行一次,叫立即执行函数
例子:

(function(){
alert("一个匿名函数");
})();

使用()括起function(){}是因为直接使用function,而不带个值var name=function(){}是会报错的,解析器只会认识{}这里的代码块。而不知道前面的function。所以要使用要带一个()括起。
最后面跟的()是调用该函数,因为前面代码本身就是个函数,使用()就能调用了。

4函数的两个方法

call()和apply()

  • 当函数对象调用这两个方法时,都会调用函数执行,设函数fun,fun(),fun.call()和fun.apply()结果都是执行了函数。
  • 但是,在调用call()和apply()时,可以将一个对象指定为第一个参数,而这个对象将会成为函数执行时的this。例如fun.call(obj);
  • call()方法可以将实参在对象后依次传递,fun.call(obj,a,b)
  • apply()与call()方法类似,但是它要将实参封装到数组里统一传递,否则报错。例如:fun.apply(obj,[a,b]);

3.作用域

作用域表示一个变量的作用范围。
JS中一共有两种作用域。

1.全局作用域

  • 直接编写在script标签下的js代码都在全局作用域下,全局作用域在页面打开时创建,在页面关闭时销毁。
  • 在全局作用域中,有一个全局对象Window,它代表的是一个浏览器的窗口,可直接使用。
  • 全局作用域下,我们创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存。(本质)
  • 在全局作用域中的变量都是全局变量,页面的任意部分都能访问到。
var a=123;
console.log(window.a);//输出123
console.log("b="+b);//输出undefined,而不是报错,因为有声明
var b=345;//b的声明和赋值在后面,可是为什么呢?怎么就声明了

注意一个特点

  • 变量的声明提前
    js中的变量声明会提前,使用var关键字声明的变量,会在所有代码执行之前被执行(仅是声明,赋值不会一起被执行,执行到该行时再执行),声明变量不使用var关键字时,变量不会被提前声明。

  • 函数的声明提前
    使用函数声明形式(function 函数名(){})创建的函数会在所有代码执行之前被创建(提前优先执行了),所有可以在函数声明前的位置就调用该函数。
    使用函数表达式(var 函数名=function(){})的函数不会被提前声明,不能在之前的位置进行调用。

    2.函数作用域

    • 调用函数时创建函数作用域,函数执行完毕后销毁。
    • 每调用一次函数就会创建一次函数作用域,彼此相互独立,互不影响。
    • 在函数作用域中可以访问的到上一级作用域(一直到全局作用域)的变量,而上一级作用域无法访问函数作用域中的变量。
    • 当函数作用域内在操作一个变量时,它会先在自身函数作用域内寻找,没有就会往上一级寻找,直到全局作用域,全局作用域中再没有就会报错ReferenceError。
    • 在函数中想要指向访问全局变量,可以使用window对象(window.属性名)
    • 函数声明提前和变量声明提前同样适用。
    • 在函数中,不使用var声明的变量(如果上一级到全局有该变量就会修改),会直接成为全局变量。相当于window.属性名=?;
    • 定义形参就相当于在函数作用域中声明了变量。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值