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;
}
}
JS高级学习路线——面向对象进阶的更多相关文章
- JS高级---学习roadmap---5 parts
JS高级---学习roadmap---5 parts part 1-3 part 4-5
- JS高级学习历程-1
JS高级-34-昨天内容回顾 时间:2015-5-11 1.DOM获取元素节点 document.getElenmentById(id 属性值) ...
- Python学习之面向对象进阶
面向对象进阶当然是要谈谈面向对象的三大特性:封装.继承.多态 @property装饰器 python虽然不建议把属性和方法都设为私有的,但是完全暴露给外界也不好,这样,我们给属性赋值的有效性九无法保证 ...
- 转:JS高级学习笔记(8)- JavaScript执行上下文和执行栈
必看参考: 请移步:博客园 JavaScript的执行上下文 深入理解JavaScript执行上下文和执行栈 JavaScript 深入之执行上下文 写在开头 入坑前端已经 13 个月了,不能再称自己 ...
- js高级程序设计 笔记 --- 面向对象的程序设计
1,理解对象 通过对象字面量的方式,创建一个对象,为它添加属性和方法: var obj = { a: 1, b:2, sayA(){ console.log(this.a)}} 1,属性类型: 数据属 ...
- JS高级学习历程-15
昨天内容回顾 面向对象的私有成员.静态成员 私有成员:在构造函数里边定义局部变量,就是私有成员. 静态成员:在js里边,函数就是对象,可以通过给函数对象声明成员方式声明静态成员. 原型继承 关键字:p ...
- JS高级学习历程-14
昨天内容回顾 1. 面向对象的私有成员.静态成员 私有成员:在构造函数里边定义局部变量,就是私有成员. 静态成员:在js里边,函数就是对象,可以通过给函数对象声明成员方式声明静态成员. 2. 原型继承 ...
- JS高级学习历程-10
[面向对象] 面向对象的三大特性:封装.继承.多态 封装:在“类”里边有关键字public.protected.private 对成员进行声明,这样每个成员的访问都会受到不同关键字的限制. 继承:在p ...
- python学习总结(面向对象进阶)
-------------------类属性和实例属性关系------------------- 1.类属性和实例属性关系 1.实例属性 实例对象独有的属性 2.类属性 ...
随机推荐
- web前端页面性能
前段性能的意义 对于访问一个网站,最花费时间的并不是后端应用程序处理以及数据库等消耗的时间,而是前端花费的时间(包括请求.网络传输.页面加载.渲染等).根据web优化的黄金法则:80%的最终用户响应时 ...
- 关于NoClassDefFoundError和ClassNotFoundException异常
java.lang.NoClassDefFoundError 和 java.lang.ClassNotFoundException 都是 Java 语言定义的标准异常.从异常类的名称看似乎都跟类的定义 ...
- 模拟做饭系统(java+线程中的join方法)
(一)项目框架分析 妈妈要去做饭,发现没有酱油,让儿子去买酱油,然后回来做饭. 根据面向对象的思想,有两个对象,妈妈和儿子 主要有两个方法: (一)没有线程控制(即儿子没有买酱油回来妈妈就做好饭了)+ ...
- HttpClient 工具
什么是httpclient HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 ja ...
- JavaScript基础——变量、语句、注释
一.变量的命名规则 1.变量名由数字.字母.下划线组成 2.变量名的首字母不能是数字,只能是字母或者下划线 3.不能使用关键字和保留字作为变量名 4.变量严格区分大小写,例如在JavaScript中o ...
- 如何用好消息推送(JPush)为app拉新、留存、促活
如何用好消息推送(JPush)为app拉新.留存.促活 作为移动端APP产品运营最重要的运营手段,消息推送(JPush)被越来越多的APP厂商所重视,在信息泛滥的移动互联网时代,手机APP应用安装得越 ...
- TypeScript设计模式之策略、模板方法
看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...
- vim编辑器的常见使用功能
Vim是一个类似于vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性. 掌握简单的vim命令可以大大提高我们编辑文档效率,在装有vim编辑器的linux系统终端输入vim ...
- MySQL优化四(优化表结构)
body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10 ...
- 【js数据结构】栈解决佩兹糖果盒问题
现实生活中栈的一个例子是佩兹糖果盒. 想象一下你有一盒佩兹糖果, 里面塞满了红色. 黄色和白色的糖果, 但是你不喜欢黄色的糖果. 使用栈( 有可能用到多个栈) 写一段程序, 在不改变盒内其他糖果叠放顺 ...