面向对象之对象,作用域及this

object
eg:
var o = {
    a : 2,
    b : 3
};
console.log(o);
console.log(typeof o);
console.log(o.a.toFixed(2));
==>
var o = new Object();
o.a = 2;
o.b = 3;
console.log(o);
console.log(typeof o);
console.log(o.a.toFixed(2));

eg:
var person = {
    name: “张三”,
    age: 26,
    gender: “男”,
    eat: function( stuff ) {
        alert( “我在吃” + stuff );
    }
 };
 person.height = 176;
 delete person[ “age” ];

 使用函数构造器构造对象
 每个构造器实际上是一个 函数(function) 对象, 该函数对象含有一个“prototype”属性用于实现 基于原型的继承(prototype-based inheritance)和 共享属性(shared properties)。对象可以由“new 关键字 + 构造器调用”的方式来创建

 // 构造器 Person 本身是一个函数对象
 function Person() {
     // 此处可做一些初始化工作
 }
 // 它有一个名叫 prototype 的属性
 Person.prototype = {
    name: “张三”,
    age: 26,
    gender: “男”,
    eat: function( stuff ) {
        alert( “我在吃” + stuff );
    }
 }
 // 使用 new 关键字构造对象
 var p = new Person();
scope
eg0:
var authorName="山边小溪";
function doSomething(){
    var blogName="梦想天空";
    blogTitle="面向对象";
    function innerSay(){
        alert(blogName);
    }
    innerSay();
}
doSomething();
innerSay();

eg1:
function foo(){
    function bar(a){
        i = 3;
        console.log(a+i);
    }
    for(var i=0; i<10 ; i++){
        bar( i*2) ;
    }
}
foo();

eg2:
var a = 2;
var obj = {
    a : 4
};
(function foo(that){
    var a = 3;
    console.log(a);
    console.log(this.a);
    console.log(that.a);
})(obj);
foo();

//eval()
function foo(str,a){
    eval(str);
    console.log(a,b);
}
var b = 2;
foo("var b = 3;",1);

//with()
function foo(obj){
    with(obj){
        a = 2;
    }
}
var o1 = {
    a = 3;
}
var o2 = {
    b = 3;
}
foo(o1);
console.log(o1.a);
foo(o2);
console.log(o2.a);
console.log(a);

//let与var
foo();
function foo(){
    console.log(q);
    var q=1;
}

foo();
function foo(){
    console.log(q);
    let q=1;
}

//变量提升
foo();
bar();
var foo = function bar(){
    ..
}
=>
var foo;
foo();
bar();
foo = function(){
    var bar=...self...
    ..
}
引擎会在解释js代码之前首先对其进行编译,而编译的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。
——> 包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。
——> 声明提升赋值和其他运逻辑会留在原地
——> 函数表达式,包括具名函数表达式不会被提升
——> 函数先提升,然后才是变量

eg3:
name = 'a';
function test(){
    var name = 'b';
    function local1(){
        var name = 'c';
        console.log(name);
    }
    function local2(){
        console.log(name);
    }
    local1();
    local2();
}
test();
this
eg1:
function a(){//当前调用栈是a,因此a的调用位置是全局作用域
    console.log('a');
    b();// b的调用位置
}
function b(){//当前调用栈是a->b,因此a的调用位置是a
    console.log('b');
    c();// c的调用位置
}
function c(){//当前调用栈是a->b->c,因此a的调用位置是b
    console.log('c');
}
a(); // a的调用位置
debugger;调试工具中分析call stack

eg2:
function foo(){
    console.log(this.a);
}
var a = 2;
foo();

function foo(){
    'use strict'
    console.log(this.a);
}
var a = 2;
foo();

eg3:
function test(){
    console.log(this.a);
}
var obj = {
    a: 2,
    test :test
}
obj.test();

eg4:
function foo(){
    console.log(this.a);
}
var obj ={
    a:2,
    foo:foo
}
var bar = obj.foo;
var a = 3;
bar();

eg:
var x = 2;
function test()
{
 this.x = 1;
}
var b = new test();
alert("b.x: " + b.x);
b.x = 3;
test();
x*=10;
alert("b.x: " + b.x);
alert("x: " + x);
var b = {};
b.x = 4;
b.test = test;
b.test();
alert("b.x: " + b.x);
var b = {};
b.x = 4;
b.test = test;
x += 5;
b.test.apply();
alert("b.x: " + b.x);
alert("x: " + x);
var b = {};
b.x = 4;
b.test = test;
x += 5;
b.test.apply(b)
alert("b.x: " + b.x);
alert("x: " + x);

eg:
var name = "I am window";
var obj = {
    name:"xiaoming",
    job:"software",
    ftn01:function(obj){
        obj.show();
    },
    ftn02:function(ftn){
        ftn();
    },
    ftn03:function(ftn){
        ftn.call(this);
    }
};
function Person(name){
    this.name = name;
    this.show = function(){
        console.log("姓名:" + this.name);
        console.log(this);
    }
}
var p = new Person("Person");
obj.ftn01(p);
obj.ftn02(function(){
   console.log(this.name);
   console.log(this);
});
obj.ftn03(function(){
    console.log(this.name);
    console.log(this);
});

情形一:传入的参数是函数的别名,那么函数的this就是指向window;

情形二:传入的参数是被new过的构造函数,那么this就是指向实例化的对象本身;

情形三:如果我们想把被传入的函数对象里this的指针指向外部字面量定义的对象,那么我们就是用apply和call

如果在javascript语言里没有通过new(包括对象字面量定义)、call和apply改变函数的this指针,函数的this指针都是指向window的

上一篇:Entity Framework Lambda 实现多列Group by,并汇总求和


下一篇:SpringMVC异常处理器