一、对象基础
1、概述:Object类型,称为一个对象,是JavaScript中的引用数据类型。它是一种复合值,它将很多值聚合到一起,可以通过名字访问这些值
2、创建对象的方式
var person = new Object();
person.name = 'luo'
person.age = 22
person.sex = '男'
console.log(person)
var son = {
name : 'luo',
age : 22,//注意区别
sex : '男'
}
console.log(son)
访问相关属性时
使用 . 来访问即可对象.属性名
person.name
son.name
delete相关属性:delete 对象.属性名
3、for … in语句进行遍历
在idea输入forin自动帮你
var father = {
name : 'luo',
age : 45,
sex : '男'
}
for (var fatherKey in father) {
var fatherVal = father[fatherKey];
console.log(father + "+" + fatherVal)
}
4、引用数据类型注意点
- 引用类型的值是保存在内存中的对象。
- 当一个变量是一个对象时,实际上变量中保存的并不是对象本身,而是对象的引用。
- 当从一个变量向另一个变量复制引用类型的值时,会将对象的引用复制到变量中,并不是创建一个新的对象。这时,两个变量指向的是同一个对象。因此,改变其中一个变量会影响另一个
二、函数
1、简单了解
函数是由一连串的子程序所组成的,可以被外部程序调用,向函数传递参数之后,函数可以返回一定的值
2、创建函数和调用
第一种
var 函数名 = function(参数){
···代码
}
var func = function (){
console.log("你好");
}
第二种
function 函数名(参数){
···代码
}
function func(){
console.log("你好");
}
调用函数方式
无参就:函数名()
var func = function (){
console.log("你好");
}
func();//结果:你好
有参就加参数:函数名(参数1,参数2)
var func = function (num1,num2){
var result = num1 + num2;
console.log(result);
}
func(1,99);//结果:100
参数注意点:
- 参数传递都是值传递,就是说把函数外部的值赋值给函数内部的参数,就和把值从一个变量赋值给另一个变量是一样的,在调用函数时,可以在()中指定实参,实参将会赋值给函数中对应的形参
- 调用函数时,解析器不会检查实参的类型,所以要注意,是否有可能会接收到非法的参数
- 调用函数时,解析器也不会检查实参的数量,多余实参不会被赋值
同样js中return也能设置函数的返回值:return 值
注意点:return后的语句都不会执行,如果return语句后不跟任何值就相当于返回一个undefined,如果函数中不写return,则也会返回undefined,return后可以跟任意类型的值
var funct = function(num1,num2){
return num1+num2;
}
3、嵌套函数的使用
在函数中声明的函数就是嵌套函数,嵌套函数只能在当前函数中可以访问,在当前函数外无法访问
function fun1(参数1){
function fun2(参数2){
···代码
}
fun2(参数2);
}
fun1();
function fun1(){
function fun2(){
console.log("你好");
}
fun2();
}
fun1();//结果:你好
4、立即执行函数(了解)
函数定义完,立即被调用,这种函数叫做立即执行函数,立即执行函数往往只会执行一次。
//()()的样子,理解为函数名()
(function func (){
console.log("你好");
})();
5、对象中的函数
对象的属性值可以是任何的数据类型,也可以是个函数。
console.log(typeof function(){});
当typeof function时会返回function
var 对象名 = {
func : function(参数){
···代码
}
}
//调用
对象名.func();
var luo = {
name : "LUO",
fu : function(){
console.log(this.name+" HELLO");
}
}
luo.fu();//结果:LUO HELLO
6、this注意点
- 以函数的形式调用时,this永远都是window
var luo = {
name : "LUO",
fu : function(){
console.log(name+" HELLO");//这里的name是window下的
}
}
luo.fu();/*这里的name以函数的形式被调用,默认window。
会只输出" HELLO",因为window下没有定义name*/
没有this和上面有this的一点点区别!
- 以方法的形式调用时,this就是调用方法的那个对象
var fun2 = {
name : "luo",
fu : funct
}
function funct(){
console.log(this.name)
}
fun2.fu()
就是和上面的一样的
其实就是作用范围问题
三、对象进阶
1、工厂方法进行创建对象
假设我要循环创建100个对象,显然一个一个var工作量十分大
function create(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.say = function () {
console.log(this.name);
}
return obj;
}
for (var i = 1;i <= 5;i++){
var person = create("luo"+i,12);
console.log(person)
}
2、用构造函数创建对象
优化工厂方法
function per(name,age) {
this.name = name;
this.age = age;
this.say = say;
}
function say() {
console.log(this.name)
}
var per1 = new per(123,14)
var per2 = new per("LUO",18)
var per3 = new per(456,120)
console.log(per1)
console.log(per2)
console.log(per3)
利用了构造函数进行创建
构造函数简单理解
它创建对象和返回对象都给隐藏了,使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。我们将通过一个构造函数创建的对象,称为是该类的实例。
- 所以当以构造函数的形式调用时,this就是新创建的那个对象
3、原型创建
上面代码,我为了不浪费内存,我把函数抽取出来,作为全局函数。这就存在一个问题,涉及到多人协作开发一个项目时,别人也有可能叫say这个方法,这会导致后面一系列的问题,污染全局作用域。所以有了原型对象
函数名1.prototype.属性(函数名2)(){}
function per(name,age) {
this.name = name;
this.age = age;
this.say = say;
}
per.prototype.say() {
console.log(this.name)
}
var per1 = new per(123,14)
var per2 = new per("LUO",18)
var per3 = new per(456,120)
console.log(per1)
console.log(per2)
console.log(per3)
prototype(原型)
简单理解:
- 创建的函数,解析器都会向函数中添加一个属性(prototype),这个属性对应着相应的对象,这个对象就是原型对象,即显式原型。原型对象就像一个公共区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。
- 函数为普通函数调用prototype没有任何作用,当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象
- 创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,不会影响到全局作用域
原型的作用:数据共享,节省内存空间
4、原型链问题
访问一个对象的属性时,先在自身属性中查找,找到返回, 如果没有,再沿着__proto__
这条链向上查找,找到返回,如果最终没找到,返回undefined,这就是原型链。作用就是查找对象的属性(方法)。
原型链是一种关系,是实例对象和原型对象之间的关系,这种关系是通过原型(proto)来联系的。
5、原型和原型链的扩展(prototype、proto)
6、对象继承问题
!!56后面补充!!