转码日记——Javascript笔记(6)

方法

对象的属性可以是任何数据类型,也可以是函数(函数就是对象)

//创建一个对象
var obj = {
    age = 99,
    name = flat };
//向对象中添加一个函数作为其属性之一
obj.sayName = function(){
    console.log("obj.name");
};
//调用方法
obj.sayName();

如果一个函数作为一个对象的属性保存,那么这个函数就是这个对象的方法,调用函数就是调用对象的方法(method)

枚举对象中的属性

对于别人创建的对象,需要知道对象中具体的属性。

//枚举的语法:
for(var 变量 in 对象){
    语句
}

//对象有几个属性,循环体就会执行几次
for(n in obj){
    console.log(n); //每次执行时,会将对象中的一个属性名字赋值给n
    console.log(obj.[n]); //取出属性值
} 

作用域(scope) :一个变量的作用范围

(1)全局作用域  — 直接编写在<script>标签中的JS代码,都在全局作用域;全局作用域在页面打开时创建,关闭时销毁;在全局作用域中有一个全局对象window,它代表的是浏览器窗口,由浏览器创建,可以直接使用;在全局作用域中,创建的变量都会作为window对象的属性保存

function fun(){
    alert("hello");
}
//fun 作为函数保存在window这个对象中
window.fun(); //也可以直接调用函数

//变量的提前声明 

//使用var关键字声明的变量,会在代码执行前被声明
console.log(a);
var a = 123; //返回undefined
//因为是这样的顺序:
var a;
console.log(a);
a = 123; 

//但是声明变量的时候不使用var关键字,则变量不会被提前声明

//函数的声明提前

//使用函数声明 function(){}创建的函数会在所有代码执行前被创建
//所以可以在函数声明前先调用函数

fun();
function fun (){
    console.log("你好");
}

//使用函数表达式创建的函数不会被提前声明
var fun = function (){
     console.log("你好");
};

全局作用域中定义的变量是全局变量,在页面中的任意部分都可以访问

(2)函数作用域 — 调用函数时创建函数作用域,函数执行完毕后销毁;每调用一次函数就会创建一个新的函数作用域,他们之间时互相独立的;在函数作用域中可以访问到全局变量;

var a =10;
function fun(){
    var a = "你好";
    console.log(a);
}
fun();//返回“你好”
//当在函数作用域操作一个变量时,它会现在自身作用域中寻找
//如果当前作用域没有该变量,则向上一级寻找,上一级可能是函数作用域也可能是全局
//如果全局中还没有找到则会报ReferenceError

function fun3(){
    console.log(a);
    var a = 12;
}
fun3(); //返回undefined
//在函数作用域中也有声明提前的特性,使用var关键字声明的变量,会在函数中所有代码执行前被声明

function fun3 (){
    fun4();
    function fun4(){
        alert("我是第四个函数");}
}
fun3(); 
//函数声明也会在函数作用域中所有代码执行之前执行

var c = 33;
function fun5(){
    console.log(c);
    c = 10; 
}
fun5(); //这里输出的是33,因为局部的c在其之后复制且没有关键字var,就没有提前声明
console.log(c);//这里输出的是10,全局的c被二次赋值了
//函数内部不写var关键字会默认设置为全局变量

//定义形参就相当于在函数作用域中声明了变量
var e = 23;
function fun(e){
    //相当于在这里var e;
    alert(e);
} //返回undefined

🌟 全局作用域不可以访问函数作用域,但是反过来可以。一旦函数作用域中有var关键字,那么这个变量就是函数作用域中的变量,全局作用域的值不会被覆盖;如果函数作用域中没有使用var关键字,那么默认是在全局作用域创建了一个变量。

注意区别:

var a = 123;
function fun (){
    alert(a); 
    var a = 456;
}
fun();  //返回undefined
alert(a); //返回123,因为函数作用域中使用var关键字声明了a,全局无法访问新声明的

var a = 123;
function fun (){
    alert(a);
    a = 456; //没有var关键字相当于在全局赋值
}
fun(); //返回123
alert(a); //返回456

var a = 123;
function fun (a){
    alert(a);
    a = 456; //这里不会对全局作用域的变量a造成影响因为函数作用域定义了形参a
}
fun(); //返回undefined,设置形参就相当于var a; 但是没有赋值
alert(a); //返回123

this

解析器在调用函数时,每次都会像函数内部传递一个隐含的参数,这个隐含的参数就是this

this指向一个对象,这个对象我们称为函数执行的上下文对象

根据函数调用方式(和函数的创建方式无关)的不同,this会指向不同的对象。

function fun (){
    alert("hello");}

var obj = {name:"lexic",
           age:79,
           sayName: fun};
obj.sayName(); // 以方法的形式调用时,this就是调用方法的那个对象
fun(); //以函数形式调用时,this永远都是window
function fun(){
     console.log(this.name); //可以更加灵活,在使用不同函数的时候返回不同的值
}
var obj = {
    name:"刘星",
    age: 10,
    sayName:fun
};
var obj2 = {
    name:"夏雪",
    age: 12,
    sayName:fun
};
obj.sayName(); //返回刘星
obj2.sayName();//返回夏雪

使用工厂方式创造对象(大批量对象)

//使用函数创建对象
function createPerson(name, age, address){ //设置参数可以创建不同属性值的对象
//创建一个新对象
    var obj = new Object;
//向对象中添加属性
    obj.name = name;
    obj.age = age;
    obj.address = address;
//将新的对象返回
    return obj;
}
obj2 = createPerson("夏雨",29, "19号楼");
obj3 = createPerson("外星人",190, "Mars");

使用工厂方式创建的对象,使用的构造函数都是object,所以创建的对象都是object这个类型,就导致我们无法区分出不同类型的对象。 

 构造函数

构造函数就是一个普通的函数,创建方式和普通函数没有区别,但是函数名称最好首字母大写;调用方式需要new关键字调用

function Person(){}
var per = Person(); //普通函数的调用方法
var per = new Person(); //构造函数的调用方法

构造函数的执行流程:1.立即创建一个新的对象。2. 将新建的对象设置成函数中this,在构造函数中可以使用this来引用新建的对象。 3.逐行执行函数中的代码。4. 将新建的对象作为返回值返回。

function Person (name, age, gender){
    this.name = name; //这里和上面一样不能写死
    this.age = age;
    this.gender = gender; //this 指的是新创建的对象
}
var per = new Person("lee", 26, "man");
console.log(per);//这里返回的不再是object,而是person

使用同一个构造函数创建的对象,我们称之为一类对象,也将一个构造函数称为类。通过一个构造函数创建的对象,是该类的实例。

使用instanceof可以检查一个对象是否是一个类的实例,如果是则返回true,否则返回false。

console.log(per instanceof Person);

//所有的对象都是object的后代,所以任何对象和object进行instanceof检查时都会返回true。

如果想在每个对象中都使用一样的函数,最好把函数创建在全局作用域而不是构造函数中。

//第一种将会造成很多无意义的函数
function Person(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.sayName = function (){
        alert(this.name);
    };
}
var obj1 = new Person("小赵", 24, "woman"); 
obj1.sayName();//每次调用该方法,就会创建出一个一样的函数,完全可以共享代码

// 第二种方法就是把sayName定义在全局作用域
function Person(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.sayName = fun; 
}
function fun (){
        alert(this.name);} //只会执行一次

但是写在全局作用域会污染全局作用域的命名空间,而且定义在全局作用域中也不安全,很容易被其他程序员在不知情的情况下覆盖掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值