JavaScript之对象

对象

JavaScript的内置对象

JavaScript常见内置对象有Object、Math、String、Array、Number、Function、Boolean、JSON等,其中Object是所有对象的基类,采用了原型继承方式

Boolean:逻辑对象

  1. Boolean的声明:声明方式有两种。一是使用字面量方式声明的变量,使用typeof检测是Boolean类型;二是使用new关键字声明的变量,使用typeof检测是Object类型

    var boolean = true; // 使用字面量方式声明
    var newBoolean = new Boolean(false); // 使用 new 关键字声明
    console.log(typeof boolean); // 使用 typeof 检测的数据类型为 Boolean
    console.log(typeof newBoolean); // 使用 typeof 检测的数据类型为 Object
    
  2. Boolean转换函数:将非布尔值转换为布尔值。如果逻辑对象无初始值或初始值为0、-0、null、" "、false、undefined、NaN,那么返回的值为 false;否则,其值为 true

Number:数字对象

构造函数Number()可以不与运算符new一起使用,而直接作为转化函数来使用

  1. Number的声明

    var num1 = 10; // 字面量声明
    var num2 = new Number(10); // new 关键字声明
    console.log(typeof num1); // 使用 typeof 检测的数据类型为 Number
    console.log(typeof num2); // 使用 typeof 检测的数据类型为 Object
    
  2. Number的属性

    Number.MAX_VALUE; //MIN_VALUE:Number 对象的属性,可表示的最小数
    Number.MIN_VALUE; //MAX_VALUE:Number 对象的属性,可表示的最大数
    
  3. Number的方法

    (1)toString():Number对象的方法,将数字转为字符串,相当于num+" "

    var str = num1.toString();
    

    (2)toFixed(n):Number对象的方法,将数字转为字符串,保留n位小数,四舍五入

    var num = new Number(10.128);
    console.log(num.toFixed(2)); //保留两位小数 ,结果为 10.13
    

    (3)valueOf():Number 对象的方法,返回 Number 对象的基本数字值

    (4)toLocaleString():Number 对象的方法,将数字按照本地格式的顺序转为字符串。一 般三个为一组加逗号

    var num1 = 101123128;
    var str = num1.toString();
    var str = str.toLocaleString()
    console.log(str); // 打印结果为 101,123,128
    

    (5)toPrecision(n):Number 对象的方法,将数字格式化为指定长度,n 为不含小数点的所有位数和

    var num1 = 101123128.456123;
    var str = num1.toPrecision(10);
    console.log(str); // 打印结果为 101123128.5 一共 10 位数
    

String:字符串对象

  1. String对象的属性:length,表示字符串中的字符个数

    str.length;  //返回字符串的长度
    
  2. String对象的方法

    (1)toLowerCase():所有字符转为小写

    (2)toUpperCase():所有字符转为大写

    (3)charAt(n):截取字符串中第n个字符

    (4)indexOf(“查询子串”,index):查询从 index 开始的,第一个子串的索引。没找到返回 -1,与数组的 indexOf()方法相同

    (5)substring(begin,end):截取子串,两个参数中begin必选,end可选。只写一个参数时表示从begin开始直到最后,写两个参数时,从begin开始end结束,左闭右开

    (6)replace(“old”,“new”):将字符串中第一个old换为new

    第一个参数可以为普通字符串,也可以为正则表达式

    var str1 = str.replace("a","*"); // 只替换字符串的第一个 a 为* 
    var str1 = str.replace(/a/g,"*"); // 使用正则,替换字符串中的所有 a 为*
    

    (7)split(" "):将字符串通过指定分隔符分为数组,只传入空字符串时会把单个字符存入数组

    var str1=str.split().join();  //使用空格将字符串拆为数组后又通过空格将字符串连接
    

    注意:JavaScript的字符串不可变,String类的方法都不能改变字符串的内容,而是返回全新字符串

Date:日期对象

  1. 实例化方式

    //在没有参数的情况下对其进行实例化
    var myDate = new Date(); // 获取当前最新时间
    
    var myDate = new Date(milliseconds); //传递 milliseconds 作为一个参数
    var myDate = new Date(dateString);  //将一个日期字符串作为一个参数传递
    var myDate = new Date(year, month, day, hours, minutes,seconds, milliseconds);
    //传递多个参数来创建一个完整的日期
    
  2. 常用方法
    在这里插入图片描述

Math:算术对象

算术对象的方法:
在这里插入图片描述
算术对象的属性:
在这里插入图片描述

JavaScript自定义对象

对象的声明

  1. 字面量声明

    var obj = {
    	key1: value1, // obj 属性
    	key2: value2,
    	func : function(){} // obj 方法
    }
    
  2. new关键字声明

    var obj = new Object();
    obj.name = "小王";
    obj.say = function(){
    	console.log("我是:"+this.name);
    }
    

对象的属性和方法

  1. 调用

    (1)通过运算符(.)调用

    //对象内部:
    this.属性名
    this.方法名()
    //对象外部:
    对象名.属性名
    对象名.方法名()
    

    注意:在对象中直接写变量名,默认为调用全局变量,如果需调用对象自身属性,则必须通过 this 关键字

    (2)通过[“key”]调用

    对象名["属性名"]
    对象名["方法名"]()  //如果key中包含特殊字符,无法使用第一种方式,则必须使用第二种方式
    
  2. 删除对象的属性方法

    delete person.age; // 删除 Person 对象的 age 属性
    

面向对象

类与对象

JavaScript中类的定义方法和函数定义方法一样,所以定义类的同时就定义了构造方法

function 类名(属性名 1){
	this.属性名 1 = 属性名 1;
	this.方法名 = function(){
		// 方法中要调用自身属性,必须使用 this.属性名 调用
	}
}
//示例:
function Person(name,sex){ // 类,同时定义构造方法
 	this.eat=function(){ // 类中的方法
 	alert("eating");
 	}
	this.name = name; // 类中的属性
	this.sex = sex;
}

通过类实例化出一个新的对象,实例化对象的时候会执行构造函数

var obj = new 类名(属性 1 的具体值);
obj.属性名; // 调用属性
obj.方法(); // 调用方法

//对象属性的删除
delete 对象名.属性名
delete zhangSan.name; // 删除 zhangSan 对象的属性 name

对象与数组一样是引用数据类型,也就是说当new一个对象时,这个对象变量存储的实际上是对象的地址,在对象赋值时,赋的其实也是地址

function Person(){}
var zhangsan = new Person(); // zhangsan 对象实际存的是地址
var lisi = zhangsan; // 赋值时,实际是将 zhangsan 存的地址给了 lisi
lisi.name = "李四"; // 李四通过地址,修改了 name 属性
console.log(zhangsan.name); // 张三再通过地址打开对象,实际 name 属性值已经改变
constructor和instanceof

先定义一个类并实例化出一个对象,后面举例将以此为基础

function Person(name){
	this.name = name; // 类的属性
	this.say = function(){ } // 类的方法
}
// 从类中实例化出一个对象,并给对象的属性赋值。
var xiaowang = new Person("小王");
  1. constructor属性:返回当前对象的构造函数

    xiaowang.constructor==Person   //true
    
  2. instanceof属性:判断对象是否为某个类的实例

    console.log(xiaowang instanceof Person);  //true
    console.log(xiaowang instanceof Object);  //true
    console.log(Person instanceof Object);  //true,函数也属于对象
    
for-in:对象的遍历
for(var prop in xiaowang){
     console.log("xiaowang的属性有"+xiaowang[prop]);
}
//prop表示xiaowang这个对象的每一个键值对的键,所以用xiaowang[prop]读取每个属性的值

成员属性、静态属性和私有属性

一个类可以拥有多种不同类型的属性和方法。在类中使用 this 声明的称为成员属性,在类外部使用类名声明的称为静态属性,而在类中使用 var 声明的属性称为私有属性

  1. 成员属性,也叫实例属性,属于实例化出的对象,通过“对象.属性”调用

    alert(xiaowang.name);  //调用成员属性
    
  2. 成员方法,也叫实例方法,属于实例化出的对象,通过“对象.方法”调用

    xiaowang.say();  //调用成员方法
    //示例:
    function Person(name){
    	this.name = name;// 声明成员属性
    	this.say = function(){}// 声明成员方法
    }
    var xiaowang = new Person("小王");
    xiaowang.age = 14; // 追加成员属性
    alert(xiaowang.name); // 调用成员属性
    xiaowang.say(); // 调用成员方法
    
  3. 静态属性,也叫类属性,是属于类(构造函数)的属性,通过“类名.属性”调用

    function Person(name){}  //声明一个类
    Person.sex="男";  //声明类属性
    alert(Person.age);  //调用类属性
    
  4. 静态方法,也叫类方法,是属于类(构造函数)的方法,通过“类名.方法”调用

    function Person(name){} // 声明一个类
    Person.sex = "男"; // 声明类属性
    Person.say = function(){
    	alert(“我说话了!”);
    }; // 声明类方法
    Person.say(); // 调用类方法
    

    注意:

    成员属性是属于实例化出的对象的,会出现在新对象的属性上;而类属性是属于构造函数自己的,不会出现在新对象的属性上

    function Person(name){} // 声明一个类
    Person.sex = "女"; // 声明类属性
    var xiaowang = new Person("小王"); // new 一个对象
    alert(xiaowang.sex); // 无法调用。类属性只能用类名调用,即使用 Person.sex 调用
    
  5. 私有属性和私有方法

    function(){
        var num=1;  //私有属性
        function func(){ }  //私有方法
    }
    

    注意:

    私有属性、私有方法的作用域都只在构造函数内部有效,只能在其内部使用,在构造函数外部,无论是对象名还是类名都无法调用

    function Person(names){
    	this.name = names;
    	var sex = "男";
    	alert(sex); // 私有属性只能在类内部使用
    }
    alert(Person.sex); // 无法调用
    var xiaowang = new Person("小王");
    alert(xiaowang.sex); // 无法调用
    

this关键字

this的指向
  1. this的指向的三个基本要素:

    (1)this 指向的永远只可能是对象

    (2)this 指向谁,永远不取决于 this 写在哪,而是取决于函数在哪调用

    (3)this 指向的对象,称为函数的上下文(context),也叫函数的调用者

  2. this指向的是函数的调用者,而不是函数的声明者。也就是说this指向谁与函数调用方式息息相关

    (1)函数名()直接调用,this指向window对象

    function func(){ // 下面示例中用到的 func 函数都是指的此函数
    	console.log(this);
    } 
    func(); // this--->window 通过函数名() 调用的,this 永远指向 window 对象
    

    (2)对象.函数名()调用,this指向这个对象

    //将 func 函数名当作 obj 对象的一个方法,然后使用对象名.方法名调用,这个时候函数里面的 this 指向 obj 对象
    var obj = { // 狭义对象
    	name:"obj", 
    	func1 :func
    };
    obj.func1(); // this--->obj
    
    //对象的调用还有一种情况,就是使用 getElementById 取到一个 div 控件,是一种广义的对象,使用它调用函数,则函数中的 this 指向这个 div 对象
    document.getElementById("div").onclick = function(){ // 广义对象
    	this.style.backgroundColor = "red";
    } // this--->div
    

    (3)数组下标调用,this指向这个数组,函数作为数组的一个元素

    var arr = [func,1,2,3];
    arr[0](); // this--->arr
    

    (4)回调函数调用,函数作为window内置函数的回调函数,this指向window,如setInterval、setTimeout等

    setTimeout(func,1000); // this--->window
    

    (5)new关键字调用,函数作为构造函数,this指向新new出的对象

    var obj = new func(); // this---> 新 new 出的 obj
    

原型和原型链

一个对象的_ _ proto _ _的最终指向就是这个对象的原型链

_ _proto _ _和prototype
  1. prototype(函数的原型) 函数才有 prototype。prototype 是一个对象,指向了当前构造函数的引用地址。通过 prototype 可以为对象在运行期间添加新的属性和方法。

  2. _ _ proto _ (对象的原型对象) 所有对象都要 _proto _ 属性(这里的对象除了人们理解的狭义对象,也包括函数、数组 等对象)。当用构造函数实例化(new)一个对象时,会将新对象的 _ proto _ _属性指在构造函数的 prototype。

function Person(){}
var xiaowang=new Person();
console.log(xiaowang.__proto__==Person.prototype);  //true
原型链

由原型层层连接起来的结构就构成的原型链

function Person(){}
var xiaowang = new Person();

在这里插入图片描述

原型链的指向规则:

(1)通过构造函数 new 出的对象,新对象的__proto__指向构造函数的 prototype

(2)所有函数的__proto__ 指向 function()的 prototype

(3)非构造函数 new 出的对象的__proto__指向 Object 的 prototype

(4)Object()的 prototype 的__proto__指向 null

(5)所有对象最终都会指向 Object()的 prototype

原型属性和原型方法

原型属性和原型方法是写在构造函数的 prototype 上。当使用构造函数实例化对象时, 该属性方法会进入新对象的__proto__上

Person.prototype.name = ""; 
Person.prototype.func = function(){};
//习惯上将属性写为成员属性,方法写为原型方法
function Person(){
	this.name = "xiaowang";
}
Person.prototype.say = function(){}

封装

把属性和方法封装成一个类,并通过类名拿到对象,就是类的封装;将一段段重复使用的代码封装成一个个方法是方法的封装;属性的封装就是将类中的属性进行私有化处理,对外不能直接使用对象名访问私有属性,同时需要提供专门用于设置和读取私有属性的get/set方法,让外部使用人们提供的方法对属性进行操作

继承

子类继承父类,子类可以自动拥有父类的所有属性和方法

实现继承的方法
  1. 扩展 Object 的 prototype 实现继承 :通过循环,将父类对象的所有属性和方法,全部赋给子类对象。关键点在于 for-in 循环,即使不扩展 Object,也能通过简单的循环实现操作。

    本质:自己写个方法,将父类的所有属性和方法通过遍历循环,逐个复制给子类

    1.声明父类
    function Parent(){}
    2.声明子类
    function Child(){}
    3.通过原型给Object对象添加一个扩展方法
    Object.prototype.customExtend=function(parObj){
        for(var i in parObj){  //通过for-in循环,把父类所有属性方法赋值给子类
            this[i]=parObj[i];
        }
    }
    4.子类对象调用扩展方法
    Child.customExtend(Parent);
    

    缺点:(1)无法通过一次实例化直接得到完整子类对象,而需要先取到子类和父类对象,再手动合并

    ​ (2)扩展Object的继承方法会保留在子类对象上

  2. 使用原型实现继承:就是将子类的prototype指向父类对象。将父类对象赋值给子类的 prototype,那么父类对象的属性和方法就会出现在子类的 prototype 中。那么实例化时,子类的 prototype 又会到子类对象的__proto__ 中,最终父类对象的属性和方法会出现在子类对象的__proto__中

    1.声明父类
    function Parent(){}
    2.声明子类
    function Child(){}
    3.把在子类对象的原型对象声明为父类的实例
    Child.prototype=new Parent();
    

    特点:(1)子类自身的所有属性都是成员属性,父类继承过来的属性都是原型属性

    ​ (2)无法通过一步实例化拿到完整的子类对象

  3. 使用 call 和 apply 实现继承:通过函数名调用方法,强行将函数中的this指向某个对象。定义子类时,在子类中使用三个函数调用父类,将父类函数的 this 指向为子类函数的 this

    func.call(func的this指向的obj,参数1,参数2....);  //call写法
    func.apply(func的this指向的obj,[参数1,参数2....]);  //apply写法
    

    具体步骤:

    1.声明父类
    function Parent(){}
    2.声明子类
    function Child(){}
    3.在子类中通过call方法或者apply方法去调用父类
    function Child(){
        Parent.call(this,....);  //将父类函数中的this强行绑定为子类的this
    }
    

闭包

https://www.runoob.com/js/js-function-closures.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值