JS高级学习路线——面向对象进阶

构造函数进阶

使用构造函数 创建对象

用于创建对象 其除了是一个函数之外,我们又称之为构造对象的函数 - 简称构造函数

    function Product(name,description){
    //属性
   this.name=name;
    // 属性
    this.description = description
    //方法 又称方法属性 万物皆属性
    this.buy=function(){
        alert('buy')
    }
 }

    //会拷贝一份
    var p1 = new Product()
    var p2 = new Product()
  //实例p1,p2的构造函数是谁 console.log(p1.constructor) console.log(p2.constructor)

如何判断某个实例是否是根据某个构造函数创建的
if(p1 instanceof Product){
alert('true')
}

存在的问题
每个实例的name,描述确实不一样,需要单独的空间存储,但是buy方法是所有实例都一样的

为了避免内存浪费,所以出现了原型帮助我们解决这个问题

原型对象 不管你实例化多少次,都只生成一次

四种创建方式

1.传参形式

2.默认值

3.动态添加形式

4.混合模式

函数声明和函数表达式的区别


搭积木开发 -- 代码可读性极高

 //产品对象
 /*类 -- 抽象对象*/
 function Product(name,price) {
        /*属性 行为 可以为空或者给默认值*/
        this.name=name
        this.price=0;
        /*我们的需求:自动计算打折后的价格*/
        /*形象的理解:包装*/
        Object.defineProperty(this, "price", {
            get: function () {return price*0.9;},
            set: function (value) {
                /*大概普通产品的价格都在0--1万*/
                if(value>10000)
                {
                    alert('产品价格必须在0--1万之间');
                }else{
                    price = value;
                }
            }
        });
    }

    //定义对象的两种方式
    Product.prototype={
        getPrice:function() {
            return this.price
        },
        addToCart:function(){
            alert('将物品添加到购物车')
        }
    }

    Product.prototype.buy=function(){}
    Product.prototype.addToCart=function(){}

    /*获取元素*/
    var btn = document.getElementById('btn')
    var name = document.getElementById('pname')

 window.onload=function() {
        /*实例化 -- 实例 -- 具体*/
        //如何使用
        //对象的使用必须先实例化,对象定义好之后,都是抽象的,必须实例化成具体
        var iphone = new Product()

        /*给对象的赋值赋值,也可以新增属性*/
        iphone.name='iphone7'
        iphone.price=6000

        /*绑定元素*/
        /*通过点语法访问对象中的属性或者方法*/
        name.innerHTML=iphone.name
        price.innerHTML=iphone.price

        /*绑定事件*/
        btn.onclick = function(){
            iphone.addToCart()
        }
    }

  

对象属性进阶1 get set权限

产品对象

1.对象内如何使用对象的属性和方法:this

2.对象外如何使用:先实例化,后用点语法

类 -- 抽象对象

    function Product(name,price) {
        /*属性 行为 可以为空或者给默认值*/
        this.name=name
        this.price=0;
        this.description = '';
        this.zhekou = ''
        this.sales = ''
        /*我们的需求:自动计算打折后的价格*/
        /*形象的理解:包装*/
        Object.defineProperty(this, "price", {
            get: function () {return price*0.9;},
            set: function (value) {
                /*大概普通产品的价格都在0--1万*/
                if(value>10000)
                {
                    alert('产品价格必须在0--1万之间');
                }else{
                    price = value;
                }
            }
        });
    }

  get set 日期 拓展性知识

Object.defineProperty(this, "produceDate", {
            get: function () {
                return dateFormat(produceDate,'yyyy-MM-dd');
            },
            set: function (value) {
                produceDate = value;
            }
        });
function dateFormat(date,format) {
        var o = {
            "M+" : date.getMonth()+1, //month
            "d+" : date.getDate(),    //day
            "h+" : date.getHours(),   //hour
            "m+" : date.getMinutes(), //minute
            "s+" : date.getSeconds(), //second
            "q+" : Math.floor((date.getMonth()+3)/3),  //quarter
            "S" : date.getMilliseconds() //millisecond
        }
        if(/(y+)/.test(format)) format=format.replace(RegExp.$1,
                (date.getFullYear()+"").substr(4- RegExp.$1.length));
        for(var k in o)if(new RegExp("("+ k +")").test(format))
            format = format.replace(RegExp.$1,
                    RegExp.$1.length==1? o[k] :
                            ("00"+ o[k]).substr((""+ o[k]).length));
        return format;
    }

  权限的设置——可读

/*我们的需求:自动计算打折后的价格*/
        Object.defineProperty(this, "price", {
            value:5000000,
            writable: t,
        });

  


 

对象属性进阶2 公有私有属性

对象构造函数

    // 私有属性好处: 安全 就类似闭包中的函数一样 减少污染
    function Person(name) {
        //私有属性,只能在对象构造函数内部使用
        var className = "用户对象";
        //公有属性,在对象实例化后调用
        this.name = name;
        //私有方法
        var privateFunction = function () {
            alert(this.name);
        }
        //公有方法
        this.publicFunction = function () {
            alert(this.name); //公有属性
            alert(className); //正确 直接通过变量名访问
            alert(this.className); //undefined 错误 不能这样访问
        }
        //公有属性
        alert(className);
        //正确 直接通过变量名访问
        alert(this.className); //undefined 错误 不能这样访问
    }

什么是公有属性:
使用象的人可以访问到对象内部的某个属性

init函数的引入

Product.prototype={
    /*初始化函数的引入*/
        /*我们将开发某个功能的初始化的工作都放在一起函数里面,用户只需要只要这一个工具就可以了*/
        init:function(){
            this.bindDOM()
            this.bindEvents()

        },
     bindDOM:function(){},
    bindEvents:function(){}
}

私有成员的引入

    //产品对象
    /*类 -- 抽象对象*/
    function Product(name,price) {
        /*属性 行为 可以为空或者给默认值*/
        this.name=name
        this.price=1000;
        this.description = '';
        this.produceDate
        /*我们的需求:自动计算打折后的价格*/
        Object.defineProperty(this, "price", {
            value:5000000,
            writable: false,
        });
        var that = this;//改变this指向
        function bindDOM(){
            /*获取元素*/
            var btn = document.getElementById('btn')
            var name = document.getElementById('pname')
            /*绑定元素*/
            /*通过点语法访问对象中的属性或者方法*/
            name.innerHTML=that.name
            price.innerHTML=that.price
        }
        function bindEvents(){
            var btn = document.getElementById('btn')
            /*绑定事件*/
            btn.onclick = function(){
                that.addToCart()
            }
        }
        this.init = function(){
            /*访问方式:不加this*/
            bindDOM()
            bindEvents()
        }
    }
    //定义对象的两种方式
    Product.prototype={
        getPrice:function() {
            return this.price
        },
        addToCart:function(){
            alert('将物品添加到购物车')
        }
    } 

config

        var that = this;
        //定义一个变量 :这个变量可以被对象中所有的属性访问到。。。。
        /*避免重复,减少内存*/
        /*统一管理*/
        this.config = {
            btnConfirm: document.getElementById('btn'),
            btnBuy: document.getElementById('btn'),
            sum :  1000,
            des :  document.getElementById('pdes'),
            youhuijia :  document.getElementById('pyouhui'),
            zhekou :  document.getElementById('pzhekou')
        }
        function bindDOM(){
            that.config.name.innerHTML=that.name
        }

对象实例进阶

数据类型的复习

//数值型
var num1 = 1;
//字符串型
var num2 ='2333fgfgfggggggggggggggggggggg';
//布尔型
var num3 =false;
//对象型
var num4 = document.getElementById('mydiv');
//未定义
var num5; 

call

    console.log(toString.call(123)) //[object Number]

    var num = 123;

    console.log(num.toString())  //toString() 方法可把一个逻辑值转换为字符串,并返回结果

数据类型检测进阶

数据类型判断 - typeof

    console.log(typeof undefined)//'undefined'
    console.log(typeof null) // well-known bug
    console.log(typeof true) //'boolean'
    console.log(typeof 123)  //'number'
    console.log(typeof "abc")  //'string'
    console.log(typeof function() {}) //'function'
    var arr=[];
    console.log(typeof {}) //'object'
    console.log(typeof arr)//'object'
    console.log(typeof unknownVariable) //'undefined'
    //    在使用 typeof 运算符时采用引用类型存储值会出现一个问题,
    //    无论引用的是什么类型的对象,它都返回 "object"

数据类型判断 - toString.call
通用但很繁琐的方法: prototype

    console.log(toString.call(123))          //[object Number]
    console.log(toString.call('123'))        //[object String]
    console.log(toString.call(undefined))    //[object Undefined]
    console.log(toString.call(true))         //[object Boolean]
    console.log(toString.call({}))           //[object Object]
    console.log(toString.call([]))           //[object Array]
    console.log(toString.call(function(){})) //[object Function]

    console.log(Object.prototype.toString.call(str) === '[object String]')   //-------> true;
    console.log(Object.prototype.toString.call(num) === '[object Number]')   //-------> true;
    console.log(Object.prototype.toString.call(arr) === '[object Array]')    //-------> true;
    console.log(Object.prototype.toString.call(date) === '[object Date]')     //-------> true;
    console.log(Object.prototype.toString.call(fn) === '[object Function]') //-------> true;

     数据类型判断 - instanceof

   //    判断已知对象类型的方法: instanceof
    console.log(arr instanceof Array)     //---------------> true
    console.log(date instanceof Date)     //---------------> true
    console.log(fn instanceof Function)   //------------> true
    //alert(f instanceof function)        //------------> false
    //注意:instanceof 后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。

     数据类型判断 - 根据对象的constructor判断: constructor

 //    根据对象的constructor判断: constructor
    var arr=[];
    console.log('数据类型判断 - constructor')
    console.log(arr.constructor === Array)   //----------> true
    console.log(date.constructor === Date)   //-----------> true
    console.log(fn.constructor === Function) //-------> true

数据类型判断 函数封装

 判断变量是不是数值型

    function isNumber0(val){
         return typeof val === 'number';
         }

//    但有些情况就不行,比如:
//    1 var a;
//    2 alert(isNumber(parseInt(a)));
//    但实际上变量a是NaN,它是不能用于数值运算的。
//    所以上面的函数可以修改为:

     function isNumber(val){
        return typeof val === 'number' && isFinite(val);
        }

//    顺便介绍一下JavaScript isFinite() 函数,isFinite() 函数用于检查其参数是否是无穷大,
//    如果 number 是有限数字(或可转换为有限数字),
//    那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。

    判断变量是不是布尔类型

 function isBooleanType(val) {
        return typeof val ==="boolean";
    }

  判断变量是不是字符串类型

 function isStringType(val) {
        return typeof val === "string";
    }

 判断变量是不是Undefined

 function isUndefined(val) {
        return typeof val === "undefined";
    }


    var a;//a是undefined
    var s = "strType";
    alert("变量a是Undefined的判断结果是:"+isUndefined(a));
    alert("变量s是Undefined的判断结果是:"+isUndefined(s));

判断变量是不是对象

function isObj(str){
        if(str === null || typeof str === 'undefined'){
            return false;
        }
        return typeof str === 'object';
    }
    var a;
    var b = null;
    var c = "str";
    var d = {};
    var e = new Object();
    alert("变量a是Object类型的判断结果是:"+isObj(a));//false
    alert("变量b是Object类型的判断结果是:"+isObj(b));//false
    alert("变量c是Object类型的判断结果是:"+isObj(c));//false
    alert("变量d是Object类型的判断结果是:"+isObj(d));//true
    alert("变量e是Object类型的判断结果是:"+isObj(e));//true

判断变量是不是null

function isNull(val){
        return  val === null;
    }
    /*测试变量*/
    var a;
    var b = null;
    var c = "str";
    //弹出运行结果
    alert("变量a是null的判断结果是:"+isNull(a));//false
    alert("变量b是null类型的判断结果是:"+isNull(b));//true
    alert("变量c是null类型的判断结果是:"+isNull(c));//false

判断变量是不是数组

//数组类型不可用typeof来判断。因为当变量是数组类型是,typeof会返回object。
   //方法1
    function isArray1(arr) {
        return Object.prototype.toString.call(arr) === '[object Array]';
    }
   //方法2
    function isArray2(arr) {
        if(arr === null || typeof arr === 'undefined'){
            return false;
        }
        return arr.constructor === Array;
    }

Jquery判断数据类型

//    jQuery提供一系列工具方法,用来判断数据类型,以弥补JavaScript原生的typeof运算符的不足。
//     以下方法对参数进行判断,返回一个布尔值。

//    jQuery.isArray():是否为数组。
//    jQuery.isEmptyObject():是否为空对象(不含可枚举的属性)。
//    jQuery.isFunction():是否为函数。
//    jQuery.isNumeric():是否为数字。
//    jQuery.isPlainObject():是否为使用“{}”或“new Object”生成的对象,而不是浏览器原生提供的对象。
//    jQuery.isWindow():是否为window对象。
//    jQuery.isXMLDoc():判断一个DOM节点是否处于XML文档之中。

 


 

原型对象的进阶

属性屏蔽理论

	function Product() {
		//属性
		this.name = '神仙';
		// 属性
		this.description = ''
		this.buy = function() {
			alert('构造函数对象')
		}
	}
	Product.prototype = {
		name: '魔鬼',
		buy: function() {
			alert('原型对象')
		}
	}
	var product = new Product()
	console.log(product.name)
	delete product.name
	product.name = '魔鬼2'
	console.log(product.name)
	/*原型属性屏蔽理论 -- 乌云蔽日*/
	console.log(product.buy())
        /*清除乌云*/
	delete product.buy
	//console.log(product.name)
	console.log(product.buy())     
        /*被屏蔽之后如何获取 */
	//console.log(Product.prototype.buy())       

hasOwnProperty

        //hasOwnProperty : 看是不是对象自身下面的属性
        function Product(){
            this.name='iphone'
        }
        Product.prototype={
            age:100
        }
        var iphone = new Product()
        console.log(iphone.hasOwnProperty('name'))   //true
        console.log(iphone.hasOwnProperty('age'))    //false,原型下面的属性

constructor 

        //constructor : 查看对象的构造函数
        function Product(){
         }
         var iphone = new Product();
         alert( iphone.constructor );  //Product
         var arr = [];
         alert( arr.constructor == Array );  //true

 

面相对象术语

原型构造函数

原型对象
1.原型对象里面的属性 -- 简称原型属性

Product.prototype.age = 12;

2.原型方法
Product.prototype.add=function(){}

 

//实例化 抽象 具体 实例 --- new Product ---类名
//使用的使用 需要先实例化:
var product = new Product(); //实例对象 实例
//如何访问对象里面的方法属性 -- 点语法
console.log(product.name)
product.add();

构造函数对象的属性和原型对象的属性区别
原型对象属性 原型对象方法 语法规范

    //构造函数对象的属性和原型对象的属性
    //构造函数对象属性不共享 原型对象属性共享
    var iphone =new Product('iphone')
    var android =new Product('android')

    //构造函数对象属性不共享
    console.log(iphone.name)    //iphone
    console.log(android.name)   //android



    //原型对象属性被所有实例共享
    console.log(iphone.date)    //2015/10/0
    console.log(android.date)   //2015/10/0 

字面量

    //简单字面量 - 描述现实世界
    var book ={name:'盗墓笔记',price:100}
    var product={name:'iphone4s',price:6000}
    console.log(product.name)
  //复杂字面量 var book = { name : "盗墓笔记", "main title" : "悬疑类小说", //当属性名中间有空格,或者“-”时,要用引号 把 属性名括起来 author : { //对象的属性也可以是对象 name : "徐磊", nickname : "南派三叔", works:[{name:'盗墓笔记',data:'2010'},{name:'大漠苍狼',data:'2011'},{name:'怒江之战',data:'2012'}] } }; console.log(book.name) console.log(book['main title']) console.log(book.author.name)

继承

前面讲过js中的面向对象其实是两个对象,一般构造函数对象中放置属性,原型对象中放置所有实例共享的方法
构造函数创建的实例为什么能访问原型对象的方法属性 -- 继承
构造函数对象

function Person(name, sex) {
        this.name = name;
        this.sex = sex;
    } 

// 定义Person的原型,原型中的属性可以被自定义对象引用
// 两个对象的本质关系:原型对象继承了构造函数对象,因而可以访问构造函数对象的一切方法,属性

Person.prototype = {
        getName: function() {
            return this.name;
        },
        getSex: function() {
            return this.sex;
        }
    }

  

 

posted @ 2017-04-10 22:14  李大白程序员  阅读(359)  评论(0编辑  收藏  举报