61阅读

继承和组合浅谈-深入浅出JavaScript之原型链和继承

发布时间:2017-09-20 所属栏目:深入浅出

一 : 深入浅出JavaScript之原型链和继承

Javascript语言的继承机制,它没有”子类”和”父类”的概念,也没有”类”(class)和”实例”(instance)的区分,全靠一种很奇特的”原型链”(prototype chain)模式,来实现继承。

这部分知识也是JavaScript里的核心重点之一,同时也是一个难点。我把学习笔记整理了一下,方便大家学习,同时自己也加深印象。这部分代码的细节很多,需要反复推敲。那我们就开始吧。

小试身手

原型链例子(要点写在注释里,可以把代码复制到浏览器里测试,下同)

function foo(){}              //通过function foo(){}定义一个函数对象 foo.prototype.z = 3;          //函数默认带个prototype对象属性   (typeof foo.prototype;//"object")  var obj =new foo();           //我们通过new foo()构造器的方式构造了一个新的对象 obj.y = 2;                    //通过赋值添加两个属性给obj obj.x = 1;                    //通过这种方式构造对象,对象的原型会指向构造函数的prototype属性,也就是foo.prototype  obj.x; // 1                 //当访问obj.x时,发现obj上有x属性,所以返回1 obj.y; // 2                 //当访问obj.y时,发现obj上有y属性,所以返回2 obj.z; // 3                 //当访问obj.z时,发现obj上没有z属性,那怎么办呢?它不会停止查找,它会查找它的原型,也就是foo.prototype,这时找到z了,所以返回3  //我们用字面量创建的对象或者函数的默认prototype对象,实际上它也是有原型的,它的原型指向Object.prototype,然后Object.prototype也是有原型的,它的原型指向null。                                    //那这里的Object.prototype有什么作用呢? typeof obj.toString; // ‘function'    //我们发现typeof obj.toString是一个函数,但是不管在对象上还是对象的原型上都没有toString方法,因为在它原型链的末端null之前都有个Object.prototype方法, //而toString正是Object.prototype上面的方法。这也解释了为什么JS基本上所有对象都有toString方法 'z' in obj; // true               //obj.z是从foo.prototype继承而来的,所以'z' in obj返回了true obj.hasOwnProperty('z'); // false   //但是obj.hasOwnProperty('z')返回了false,表示z不是obj直接对象上的,而是对象的原型链上面的属性。(hsaOwnProperty也是Object.prototype上的方法) 

刚才我们访问x,y和z,分别通过原型链去查找,我们可以知道:当我们访问对象的某属性时,而该对象上没有相应属性时,那么它会通过原型链向上查找,一直找到null还没有话,就会返回undefined。

基于原型的继承

function Foo(){    this.y = 2;      }  Foo.prototype.x = 1; var obj3 = new Foo();  //①当使用new去调用的时候,函数会作为构造器去调用②this会指向一个对象(这里是obj3),而这个对象的原型会指向构造器的prototype属性(这里是Foo.prototype) obj3.y; //2  obj3.x; //1    //可以看到y是对象上的,x是原型链上的原型(也就是Foo.prototype上) 

prototype属性与原型

我们再来看看Foo.prototype是什么样的结构,当我们用函数声明去创建一个空函数的时候,那么这个函数就有个prototype属性,并且它默认有两个属性,constructor和__proto__,

constructor属性会指向它本身Foo,__proto__是在chrome中暴露的(不是一个标准属性,知道就行),那么Foo.prototype的原型会指向Object.prototype。因此Object.prototype上

的一些方法toString,valueOf才会被每个一般的对象所使用。

function Foo(){} typeof Foo.prototype; // "object" Foo.prototype.x = 1; var obj3 = new Foo(); 

总结一下:我们这里有个Foo函数,这个函数有个prototype的对象属性,它的作用就是当使用new Foo()去构造实例的时候,这个构造器的prototype属性会用作new出来的这些对象的原型。

所以我们要搞清楚,prototype和原型是两回事,prototype是函数对象上的预设属性,原型通常是构造器上的prototype属性。

实现一个class继承另外一个class

function Person(name, age) {    this.name = name;    //直接调用的话,this指向全局对象(this知识点整理)    this.age = age;      //使用new调用Peoson的话,this会指向原型为Person.prototype的空对象,通过this.name给空对象赋值,最后this作为return值 }  Person.prototype.hi = function() {   //通过Person.prototype.hi创建所有Person实例共享的方法,(可以参考上节的左图:对象的原型会指向构造器的prototype属性,所以想让obj1,obj2,obj3共享一些方法的话,只需在原型对象上一次性地添加属性和方法就可以了);    console.log('Hi, my name is ' + this.name + ',I am ' + this.age + ' years old now.')//这里的this是全局对象 };  Person.prototype.LEGS_NUM = 2;   //再设置一些对Person类的所有实例共享的数据 Person.prototype.ARMS_NUM = 2; Person.prototype.walk = function() {   console.log(this.name + ' is walking...'); };  function Student(name, age, className) {  //每个学生都属于人   Person.call(this, name, age);  //在Student这个子类里面先调用一下父类   this.className = className; }  //下一步就是我们怎么去把Student的实例继承Person.prototype的一些方法  Student.prototype = Object.create(Person.prototype);    //Object.create():创建一个空对象,并且这个对象的原型指向它的参数  //这样子我们可以在访问Student.prototype的时候可以向上查找到Person.prototype,又可以在不影响Person的情况下,创建自己的方法 Student.prototype.constructor = Student;  //保持一致性,不设置的话constructor会指向Person  Student.prototype.hi = function() {    //通过Student.prototype.hi这样子的赋值可以覆盖我们基类Person.prototype.hi   console.log('Hi, my name is ' + this.name + ',I am ' + this.age + ' years old now, and from ' + this.className + '.'); } Student.prototype.learn = function(subject) {    //同时,我们又有自己的learn方法   console.log(this.name + 'is learning ' + subject + ' at' + this.className + '.'); };  //test var yun = new Student('Yunyun', 22, 'Class 3,Grade 2'); yun.hi(); //Hi,my name is Yunyun,I'm 22 years old now,and from Class 3, Grade 2. console.log(yun.ARMS_NUM); // 2     //我们本身对象是没有的,对象的原型也就是Student.prototype也没有,但是我们用了继承,继续向上查找,找到了Person.prototype.ARMS_NUM,所以返回2 yun.walk(); //Yunyun is walking... yun.learn('math'); //Yunyun is learning math at Class 3,Grade 2. 

结合图我们来倒过来分析一下上面代码:我们先通过new Student创建了一个Student的实例yun,yun的原型指向构造器的prototype属性(这里就是Student.prototype), Student.prototype上有hi方法和learn方法,Student.prototype是通过Object.create(Person.prototype)构造的,所以这里的Student.prototype是空对象,并且这个对象的原型指向Person.prototype,接着我们在Person.prototype上也设置了LEGS_NUM,ARMS_NUM属性以及hi,walk方法。然后我们直接定义了一个Person函数,Person.prototype就是一个预置的对象,它本身也会有它的原型,它的原型就是Object.prototype,也正是因为这样,我们随便一个对象才会有hasOwnProperty,valueOf,toString这样些公共的函数,这些函数都是从Object.prototype上来的。这样子就实现了基于原型链的继承。       那我们调用hi,walk,learn方法的时候发生了什么呢?比如我们调用hi方法的时候,我们首先看这个对象yun上有没有hi方法,但是在这个实例中没有所以会向上查找,查找到yun的原型也就是Student.protoype上有这hi方法,所以最终调用的是Student.prototype.hi,调用其他方法也是类似的。

改变prototype

我们知道JavaScript中的prototype原型不像Java中的class,Java中的class一旦写好就很难动态的去改变了,但是JavaScript中的原型实际上也是普通的对象,那就意味着在程序运行的阶段,我们也可以动态的给prototype添加或删除些属性。

在上述代码的基础上,我们已经有yun这个实例了,我们接着来进行实验:

tudent.prototype.x = 101;        //通过Student.prototype.x把yun的原型动态地添加一个属性x yun.x;   //101                    //那我们发现所有的实例都会受到影响 //接着我们做个有趣的实验 Student.prototype = {y:2};        //我们直接修改构造器的prototype属性,把它赋值为一个新的对象 yun.y;  //undefined                yun.x;  //101                     //所以我们得出:当我们修改Student.prototype值的时候,并不能修改已经实例化的对象 var Tom = new Student('Tom',3,'Class LOL KengB');   Tom.x; //undefined                //但当我们创建一个新的实例时,这一次x就不见了, Tom.y; //2                        //并且y是新的值 

所以说当动态修改prototype的时候,是会影响所有已创建或新创建的实例的,但是修改整个prototype赋值为新的对象的话,对已创建的实例是不会影响的,但是会影响后续的实例。

实现继承的方式

实现继承有多种方式,下面我们还是以Person和Student来分析

function Person() { }  function Student() { }  Student.prototype = Person.prototype; // 我们可不可用这种方式呢?这种方法是错误的:因为子类Student有自己的一些方法 //,如果通过这样子赋值,改变Student的同时也改变了Person。  Student.prototype = new Person(); //这种方式是可以实现的,但是调用构造函数有时候也是有问题的,比如要传进Person一个name和age //,这里的Student是个类,还没实例化,这时候有些奇怪了,传什么都不是。  Student.prototype = Object.create(Person.prototype); //相对来说这中方式是比较理想的,这里我们创建了一个空的对象 //,并且对象的原型指向Person.prototype,这样我们既保证了继承了Person.prototype上的方法,并且Student.prototype又有自己空的对象。 //但是Object.create是ES5以后才有的

 

二 : 浅谈筵席菜品组合

摘 要:一桌完美的筵席,其结构合理、口味诱人、营养全面、器皿得当,无论其价位高低,都能产生无穷的效果。一套菜品还应该原材料新鲜、时令、丰富多样,整体协调一致,丰俭适度;古今筵席都包涵着“尊重、谦让、礼仪、团圆等”内涵。

关键词:筵席;菜品组合;厨艺工程
1 筵席的设计原则
以餐饮消费者的需求为核心,以本店经营特色为重点,以酒店的基本条件、技术因素为依据,以客人完美的满意度为目标。
筵席技术含量高,艺术性强,是烹饪艺术的又一表现形式。一份精心设计编制的筵席菜单,对菜点色、形、香、味、滋的组合,餐具饮器的配置,烹调技法的运用,菜肴、羹汤、点心的排列,馔肴总体风味特色的表现,都有周密的安排。它是时代、地区、饭店(或餐馆)的烹调技术水平和烹饪艺术水平的综合反映。审美主体――与筵者的食欲、情绪、心理,均受筵席菜单设计的烹饪艺术效果的影响。
2 筵席的菜品组合
2.1 结构比例
所谓菜品结构,就是一桌菜都有哪些元素构成。一般情况下,筵席是由冷菜、大菜、热炒、饭菜、面点、水果构成。在餐饮发展的今天,美国波斯顿餐饮咨询提出来菜品四分法,即由明星菜、金牛菜、问题菜、?C狗菜组成。
传统的筵席结构要求,冷菜约为10%,大菜约为40%~45%,热炒菜约为25%,饭菜约为15%,面点、水果约为5%。宴席菜品凸显地域性和酒店的厨艺水平。消费者青睐且利润高的菜品应该为主;菜品受欢迎度高,但毛利率低的也应该有;不受欢迎且毛利又低应视为调整或淘汰菜品。
当今筵席还要把重量作为一个要素考虑。一是要考虑节约、营养过剩等;二是科学的用餐,每人以500克的计量为标准;按照地方习俗以及带骨食品等因素,筵席的人均量不得超出750克为宜。
2.2 口味组合
口味的组合在中餐筵席中是核心组合。口味是菜品的灵魂,是酒店展示厨艺的最佳平台。一桌菜品的口味组合,需要用心思考。如何体现菜肴的原味、如何展现大厨的调味技艺、如何使菜品原料与原料、原料与调料、调料与调料产生生成美味。酸甜苦辣咸、清淡、浓郁、淡雅、清香等口感用什么菜品展现。利用好有色调味品和无色调味品,使筵席脱掉黑乎乎的印象;例如运用色拉油、花生油、豆油、菜籽油、橄榄油、山茶油等,对不同的菜品进行加热和调味,就能使菜品在口味口感上产生差异化,形成美感。
2.3 色彩组合
筵席的色彩组合,不同于日常饮食。怎样使整桌筵席的色彩艳丽、光彩照人,让人产生第一美感,产生记忆,让人联想到美感,也需要烹调大师们精心设计。充分利用菜品原料的自然色泽,发挥好白色原色菜品为筵席添彩;利用调色菜品作补充;尽量使菜品的色泽少重叠,赤橙黄绿青蓝紫丰富色彩。纵观我们的普通筵席,厨师特喜欢使用青红辣椒做配料,特喜欢使用酱、酱油调味,这样就形成了菜品的色彩的重叠,直接降低筵席效果。
2.4 方法组合
筵席菜肴的烹调方法应多样化,原则上一桌筵席不能少于八种烹调方法。冷菜的拌、炝、腌、卤、酱;热炒菜的炸、溜、爆、炒、烹;大菜的蒸、烤、烧、煨、焖等。方法的多样既能展示厨师的技艺水平,又能为筵席增辉。形成菜品的差异化,达到筵席的效果。当然,如筵席规模较大,如果烹调方法复杂就会影响上菜速度,影响菜品风(www.61k.com]味特色,影响菜品的温度,降低菜品质量。烹调方法的组合也要与时俱进,在保证菜品风味、保证上菜速度的前提下,尽量丰富菜品的烹制方法。
2.5 菜品组合
筵席格局以菜肴为中心,体现艺术形式上的多样统一。筵席菜肴的多样化,通过炸、熘、爆、炒、烧等多种技法,荤素原料多种选配,丁、丝、块、条、片等多种形态,黄、红、白、绿等多种色彩,酥、脆、嫩、软等多种质地,咸、甜、鲜、香等多种味感表现其艺术性。
菜点组合排列,表现艺术节奏与旋律感。筵席菜点的这种味的起伏变化,有若音乐旋律中的节奏强弱、速度快慢、旋律高低,使审美主体与筵者越吃越有兴趣,越吃越有味道。
先声夺人的冷菜;具有震撼力的大件菜;色彩醒目、口味诱人的热炒菜;刺激、食用、味道的下饭菜等。大件菜与普通菜、无汁菜与汤羹菜、清淡菜与口味浓郁的菜、原味菜与调味菜、象形菜与家常菜等协调一致。
2.6 器皿组合
美食不如美器,好花还需绿叶配。清代的大美食家袁枚先生在《随园食单》中说:“美食不如美器,斯语是也。”在组合上分有统一器皿和个性器皿两类。根据筵席的需要也可分为豪华器皿和乡土器皿。即便是个性器皿组合,切记不要太杂乱,不要太高,不能遮挡用餐者的视线为宜。要特别注重菜品色彩、形态、纹饰、空间、寓意等之间协调配合。
综上所述,筵席菜品设计是一项系统复杂的厨艺工程,要想达到极佳的效果,必须用心设计。除上述组合要求外,还要灵活的因人设计、因时设计、因价设计、因味设计菜肴。总之,要把传统菜品做到位、创新菜品做到受欢迎、看家菜要做到规范统一、时令菜要做到新鲜、地方菜一定要做出个性来、引进的菜品要力争做成功。筵席的设计者既要有技术又要有经验,方能左右逢源、运筹帷幄。
作者简介:
吕建伟,汉,江苏海安人,任烹饪讲师,主要研究方向:烹饪实践教学。

三 : 浅谈随和

很久以来,总是在思考,什么是随和?

有人说,随和就是顺从众议,不固执己见;有人说,随和就是不斤斤计较,为人和蔼;还有人说,随和其实就是傻,就是老好人,就是没有原则。那么,随和到底是什么?

随和,是一种素质,一种文化,一种心态。随和是淡泊名利时的超然。

人要善于随和。即便原则问题,也要平等地和人家交换意见,不存成见,切莫居高临下。

要随和,就得克服“以我为中心”的思想。如果你的见识主张和能力比别人强,人际关系好,人家就有可能会尊重你.如果自己不具备这些条件,又要搞“以我为中心”。既不能满足你的欲望,又有可能毁掉你自己。斤斤计较自己的名誉,地位,什么都要比人家的好,情绪又烦躁,对自己身体必定伤害较大,会容易衰老。要人家尊重你,关键是自己要尊重人家。

做到随和的人,必定是高瞻远瞩的人,宽宏大度的人,豁达潇洒的人。而胸怀狭窄的人,做不到这点。“难得糊涂”就妙在其中。( 文章阅读网:www.61k.com )

在日常工作、生活中,只有随和的人,才能发现周围的真善美,才可以真正享受生活赐予我们的快乐。在随和中,我们可以拥有宽广的胸怀、高瞻远瞩的目光和无以伦比的智慧。

但随和决不是没有原则。随和的人,首先是聪明的人,他以睿智的目光洞察了世界;随和的人,是谦虚的人,他始终明白“尺有所短,寸有所长”的道理;随和的人,是宽宏大量的人,在人与人之间发生摩擦时,在坚持原则的基础上,他能够以谦和的态度对待对方;随和的人,是没有贪欲的人,他可以很好地控制自己的世俗欲望。

随和需要有良好的自身修养。要善于和有不同意见的人沟通,学会换位思考,学会感恩;要真诚地赞赏别人,夸奖别人;要不吝啬自己的微笑。

随和需要有与人为善的品质。“不以善小而不为,不为恶小而为之”是做人的准则。善良作为人们最美好的品质永远闪耀着人性的光辉。一个与人为善的人总是受到人们的称赞和尊重。对周围需要帮助的人,伸出热情的双手给他一份力量;面对他人过错,善意地给予谅解。与人为善,善待他人,我们就会多一份坦然,增一份愉悦,添一份好心情。如此说来,善待他人不正是善待自己吗?

品味随和的人会成为智者;享受随和的人会成为慧者;拥有随和的人就拥有了一份宝贵的精神财富;善于随和的人,方能悟到随和的真谛。

真正做到为人随和,确实需要经过一番历练,经过一番升华。

为人随和一点,我们会感受到生活更加美好!

本文标题:继承和组合浅谈-深入浅出JavaScript之原型链和继承
本文地址: http://www.61k.com/1074590.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1