javascripte 学习笔记之一

本文深入探讨JavaScript中的布尔变量、字符串处理、对象创建、原型链、继承机制、闭包及单例模式等内容,并提供了丰富的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

reading book:《javascript高级程序设计第二版》

布尔变量:

var msg;

if (msg == undefined) //true

if (undefined == null) //true

false:

empty string ""

0, NaN

null

defined

//=============================

var n = 10

n.toString('2') //1010

类的赋值为引用赋值

var obj1 = new Object();
var obj2 = obj1;
obj1.name = “Nicholas”;
alert(obj2.name);
//”Nicholas”

//===========================================
var now = new Date();

When the Date constructor is used without any arguments, the created object is assigned the current date and time.

//===========================================

函数

函数传参

如果是类,则是引用传递。

function factorial(num){
    if (num <= 1) {
             return 1;
      } else {
            return num * factorial(num-1)
     }
}

等价于

function factorial(num){
  if (num <= 1) {
    return 1;
  } else {
    return num * arguments.callee(num-1)
  }
}

//============================================

创建方法:

var person = new Object();
person.name = “Nicholas”;
person.age = 29;
person.job = “Software Engineer”;
person.sayName = function(){
    alert(this.name);
};

function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
  alert(this.name);
  };
return o;
}
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);

function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
  alert(this.name);
  };
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);

4

Person = {
  name: ''.
  age:'',
  job:'',
  sayName: function() {
       alert(this.name);
    }
};


prototype:

function Person() {

}


Person1 = new Person();

Person2 = new Person();

两个新建的实例在创建的时候,会自动包含一个__proto__的变量,这个变量指向Person的prototype,而Person的prototype是指向其Prototype。也就是说__proto__都是指向同一个Person的prototype。那么可以这么说,__proto__是类的Prototype和实例之间的一个链接,可以认为是一个引用。如果有c++的基础,我觉得可以把js的prototype看成是类的公有静态成员变量。



如果prototype的内容的不可更改的,但如果你进行了更改操作,其实这个更改操作不是对prototype进行的,而是对类的实例。


比如

person1 = new Person();

person2 = new Person();

person1.name = "My";   //为实例新建了一个name的变量,因为js的类是动态类型,所以这个是可以做到的。

alert(person1.name);   //My for instance

alert(person2.name);    //Nicholas for prototype

delete:删除实例的属性

delete person1.name

Methods:

hasOwnerProperty(arg): 判断实例是否含有某属性,不包含prototype中的属性,仅属于实例的。

in:判断实例是否含有某属性,包含prototype中的属性。

prototype的literally声明

Person.prototype = {

  // constructor: Person,
    name : “Nicholas”,
    age : 29,
    job : “Software Engineer”,
    sayName : function () {
        alert(this.name);
    }
};

此时prototype是覆盖了默认的prototype,所以没有了指向Person的constructor。在new的时候,会再自动添加prototype的constructor,但这时prototype的constructor指向的是Object。如果想要它指向的是Person,就需要在上面的声明中添加注释掉的代码。

继承:基本都有不完善的地方。

1 prototype chaining

2 constructor stealing

3 组合继承

4 Prototypal Inheritance

5 Parasitic Inheritance


1 通过prototype继承,形成prototype chaining。不好:如果父类含有引用类型,就变成就公有静态变量。

function SuperType(){
this.colors = [“red”, “blue”, “green”];
}
function SubType(){
}
//inherit from SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push(“black”);
alert(instance1.colors);
//”red,blue,green,black”
var instance2 = new SubType();
alert(instance2.colors);
//”red,blue,green,black”

2 constructor stealing。不好:会导致无法使用父类的prototype,而且方法需要写在父类的构造函数里面。

function SuperType(name){
this.name = name;
}
function SubType(){
//inherit from SuperType passing in an argument
SuperType.call(this, “Nicholas”);
//instance property
this.age = 29;
}
var instance = new SubType();
alert(instance.name);
//”Nicholas”;
alert(instance.age);
//29
3 组合继承:prototype chaining + constructor stealing。比较普遍被使用的方法

不好:调用两次父类的constructor(构造函数)

function SuperType(name){
this.name = name;
this.colors = [“red”, “blue”, “green”];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
//inherit properties
SuperType.call(this, name);
this.age = age;
}
//inherit methods
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType(“Nicholas”, 29);
instance1.colors.push(“black”);
alert(instance1.colors); //”red,blue,green,black”
instance1.sayName();
//”Nicholas”;
instance1.sayAge();
//29
var instance2 = new SubType(“Greg”, 27);
alert(instance2.colors); //”red,blue,green”
instance2.sayName();
//”Greg”;
instance2.sayAge();
//27
4 Prototypal Inheritance
function object(o){
  function F(){}
  F.prototype = o;
  return new F();
}
5 Parasitic Inheritance,避免了组合继承的两次调用父类构造函数的问题。

function inheritPrototype(subType, superType){
  var prototype = object(superType.prototype);  //clone prototype
  prototype.constructor = subType;
  subType.prototype = prototype;
}
function SuperType(name){
  this.name = name;
  this.colors = [“red”, “blue”, “green”];
}
SuperType.prototype.sayName = function(){
  alert(this.name);
};
function SubType(name, age){
  SuperType.call(this, name);
  this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
  alert(this.age);
};


闭包

function createFunctions(){
  var result = new Array();
  for (var i=0; i < 10; i++){
    result[i] = function(){
      return i;
    };
  }
  return result;
}
返回的数组的值都是10,因为在函数里,它们都是赋值为i,只有一个i!而i最后会变成10。

使用闭包:

function createFunctions(){
  var result = new Array();
  for (var i=0; i < 10; i++){
    result[i] = function(num){
      return function(){
          return num;
      };
    }(i);
  }
  return result;
}
声明匿名函数后立即调用。

var name = “The Window”;
var object = {
  name : “My Object”,
  getNameFunc : function(){
      return function(){
    return this.name;
    };
  }
};
alert(object.getNameFunc()());
//”The Window”
由于函数的两个参数,this和arguments。外部函数的this执行的是object,由于函数的this是默认执行window,所以当内部函数被调用,那么它指向的就是全局的window,因为它是作为外部函数一个普通函数调用。
that模式解决:

var name = “The Window”;
var object = {
  name : “My Object”,
  getNameFunc : function(){
    var that = this;
    return function(){
       return that.name;
    };
  }
};
alert(object.getNameFunc()());
//”My Object”
闭包的问题:会比较消耗内存,因为当外部函数执行完后,如果内部函数还在使用,那外部函数并不会从内存中删去。


模拟块作用域:

(function() {

   //block code

})();

//=========================================

singleton 单例化

var singleton = {
  name : value,
  method : function () {
  //method code here
  }
};

var singleton = function {
  var privateVal = 0;
  function privateFunc() { return false; }
  return {
    prop: true,
    publicFunc: function() {
             privateVal++;
             return privateFunc();
     }
  };
}();

可拓展的单例:

var singleton = function(){
  //private variables and functions
  var privateVariable = 10;
  function privateFunction(){
    return false;
  }
  //create object
  var object = new CustomType();
  //add privileged/public properties and methods
  object.publicProperty = true;
  object.publicMethod = function(){
    privateVariable++;
    return privateFunction();
  };
  //return the object
  return object;
}();






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值